A short explanation of InStream and OutStream

I think one of the most frequent google searches in my earlier years as a Dynamics NAV / Business Central developer was looking up the magic of InStream and OutStream handling.

So, here’s just a short explanation of InStream and OutStream.

Types of Streams

In my opinion, the major problem is that the naming of the types has always been a bit misleading. Or better, depending on how you “think”. For me it is not really logical that something is called “out” but i want to get something “in”. However, as soon as you have remembered which function the respective stream has in Dynamics NAV, you won’t get so hung up on the naming 😉

OutStream

Actually, it’s very simple with this one. If you want to write something into a File or a Blob field, you create an OutStream to dump your data in. Whether this is text using Write(), WriteText() method or the copy of an entire InStream using CopyStream() is both possible.

We could use the new Temp Blob codeunit to store some text in it:

TempBlob.CreateOutStream(OStream);
OStream.WriteText('This is my content');

But we could also copy an “incoming” InStream to store it in the Temp Blob:

TempBlob.CreateOutStream(OStream);
CopyStream(OStream, IStream);

Or alternatively, we could write or copy to a file:

// Create the file
TempFile.CreateTempFile(TextEncoding::UTF8);
TempFile.CreateOutStream(OStream);

// Write the content
OStream.WriteText('This is my content');

// Close it
TempFile.Close();

InStream

In contrast to the OutStream, the InStream Type is there to read or work with the content of a file or Blob.

If we would like to access the content of Temp Blob we just modified in the previous example:

TempBlob.CreateInStream(IStream);

Or read the content of a e.g a text-file:

TempFile.Open('...');
TempFile.CreateInStream(IStream);
TempFile.Close();

… and just do some fancy stuff like reading text-content from the InStream:

WHILE NOT IStream.EOS DO BEGIN  
  IStream.READTEXT(TextBuffer);  
  //Do something with the TextBuffer
END;  

Or send it as the content of your POST web request (example from MSDN):

procedure MakeRequest(uri: Text; IStream: InStream) responseText: Text;
var
    client: HttpClient;
    request: HttpRequestMessage;
    response: HttpResponseMessage;
    contentHeaders: HttpHeaders;
    content: HttpContent;
begin
    // Add the InStream payload to the content
    content.WriteFrom(IStream);

    // Retrieve the contentHeaders associated with the content
    content.GetHeaders(contentHeaders);
    contentHeaders.Clear();
    contentHeaders.Add('Content-Type', 'application/octet-stream');
    request.Content := content;

    request.SetRequestUri(uri);
    request.Method := 'POST';

    client.Send(request, response);

    // Read the response content as json.
    response.Content().ReadAs(responseText);
end;

InStream and OutStream in .NET

It is very good to know, especially if you use .NET components, that NAV streams are compatible with .NET streams. In my barcode example a couple of weeks ago, I showed how to copy an InStream containing a barcode-image to a MemoryStream using the CopyStream() method and directly work with it in the .NET component:

//MemoryStream Instance
MemoryStream := MemoryStream.MemoryStream;

//Copy the NAV InStream to MemoryStream
CopyStream(MemoryStream, BarcodeInStream);

//Rewind MemoryStream
MemoryStream.Position := 0;

//Directly work in the .NET component
Bitmap := Bitmap.FromStream(MemoryStream);

... is a technical consultant and developer at Comsol Unternehmenslösungen AG in Kronberg/Taunus. Major tasks are the architecture and implementation of complex, usually cross-system applications in and around Microsoft Dynamics 365 Business Central.

Leave a Reply

Your email address will not be published. Required fields are marked *