13.2 Streams, File Management & TempBlob

Key Takeaways

  • InStream and OutStream provide sequential byte-level data streaming in AL, reading from and writing to binary buffers, files, and network connections in memory chunks without loading entire payloads into RAM.
  • The TempBlob codeunit in the System Application serves as the universal in-memory binary container, replacing the deprecated legacy TempBlob table.
  • In Business Central SaaS (target = Cloud), direct access to the server filesystem using the File data type or .NET file I/O is strictly prohibited, requiring browser stream dialogs or cloud storage APIs.
  • Interactive file transfer between the Web Client browser and the Business Central Server tier is managed via UploadIntoStream() and DownloadFromStream().
  • Codeunit 4114 Base64 Convert provides high-performance bidirectional translation between binary streams and Base64-encoded strings for JSON and REST API payloads.
Last updated: August 2026

13.2 Streams, File Management & TempBlob

In modern cloud-first architectures for Microsoft Dynamics 365 Business Central, direct access to the server's local physical filesystem is strictly blocked. All document imports, exports, image processing, report rendering, and REST API payload transformations rely on Streams and memory-backed binary containers. For the MB-820 exam, developers must master InStream, OutStream, the TempBlob codeunit, cloud file transfer dialogs, and Base64 encoding routines.


1. AL Stream Architecture: InStream & OutStream Fundamentals

Streams represent sequential sequences of bytes. Rather than loading massive text files, PDFs, or binary payloads entirely into memory as strings (which can exceed string length limits and trigger Out-Of-Memory exceptions on the NST), streams process data continuously in buffered chunks.

local procedure DemonstrateStreamProcessing()
var
    TempBlob: Codeunit "Temp Blob";
    WriteOutStream: OutStream;
    ReadInStream: InStream;
    LineContent: Text;
    RecordCount: Integer;
begin
    // 1. Initialize OutStream and write structured data
    TempBlob.CreateOutStream(WriteOutStream, TextEncoding::UTF8);
    WriteOutStream.WriteText('ItemNo,Description,UnitPrice');
    WriteOutStream.WriteText(); // Writes CRLF delimiter
    WriteOutStream.WriteText('1001,Touring Bicycle,1250.00');
    WriteOutStream.WriteText();
    WriteOutStream.WriteText('1002,Mountain Bike,1450.00');

    // 2. Initialize InStream and read sequentially line by line
    TempBlob.CreateInStream(ReadInStream, TextEncoding::UTF8);
    while not ReadInStream.EOS() do begin
        ReadInStream.ReadText(LineContent);
        RecordCount += 1;
        // Process LineContent
    end;
    Message('Processed %1 lines from stream.', RecordCount);
end;

Stream Types and Core Methods

  • InStream (Input Stream): Used to read sequential binary or text data from a source (such as a database BLOB, file upload, or HTTP response):
    • InStream.Read(Variant [, Length]): Reads raw binary bytes into a variable.
    • InStream.ReadText(Text [, Length]): Reads a string of text up to the next newline delimiter or specified character length.
    • InStream.EOS(): Returns true when the End of Stream is reached.
    • InStream.Position: Returns or sets the current byte offset within the stream.
  • OutStream (Output Stream): Used to write sequential binary or text data to a destination (such as a database BLOB, file download, or HTTP request content):
    • OutStream.Write(Variant [, Length]): Writes raw binary data to the stream.
    • OutStream.WriteText(Text): Appends text characters to the stream.
    • OutStream.WriteText(): Writes standard newline characters (CRLF).

Text Encoding Options

When initializing streams, developers should explicitly define character encoding using the TextEncoding enum:

  • TextEncoding::UTF8 (Default standard for JSON, REST APIs, XML, and modern web integrations).
  • TextEncoding::UTF16 (Wide-character Unicode).
  • TextEncoding::Windows (ANSI Windows codepage, common in legacy file exports).
  • TextEncoding::MSDos (Legacy OEM ASCII encoding).

2. The TempBlob Codeunit & In-Memory Binary Management

In legacy C/AL development, binary objects were stored and manipulated using temporary records on a system TempBlob table (Record "TempBlob" temporary). In modern AL, Microsoft deprecated the table approach in favor of the TempBlob Codeunit (Codeunit 4100 "Temp Blob" in the System Application).

local procedure StoreCustomerPicture(CustNo: Code[20]; var ImageInStream: InStream)
var
    Customer: Record Customer;
    TempBlob: Codeunit "Temp Blob";
    BlobOutStream: OutStream;
    BlobInStream: InStream;
begin
    if not Customer.Get(CustNo) then
        exit;

    // Read from source InStream and write into TempBlob container
    TempBlob.CreateOutStream(BlobOutStream);
    CopyStream(BlobOutStream, ImageInStream);

    // Verify binary payload presence and length
    if TempBlob.HasValue() then begin
        Message('Blob payload size: %1 bytes', TempBlob.Length());
        
        // Import from TempBlob into Customer Media field
        TempBlob.CreateInStream(BlobInStream);
        Clear(Customer.Image);
        Customer.Image.ImportStream(BlobInStream, 'Customer Picture', 'image/jpeg');
        Customer.Modify(true);
    end;
end;

TempBlob Codeunit Core API

  • CreateInStream(var InStream [, TextEncoding]): Creates an InStream reader pointing to the beginning of the memory buffer.
  • CreateOutStream(var OutStream [, TextEncoding]): Creates an OutStream writer, clearing any prior contents in the memory buffer.
  • Length(): Returns the total size of the binary payload in bytes as an Integer.
  • HasValue(): Returns a Boolean indicating whether the buffer contains one or more bytes (Length() > 0).
  • CopyStream(OutStream, InStream): System function that transfers all bytes from an InStream directly into an OutStream in optimized memory chunks.

Handling Table BLOB & Media/MediaSet Fields

  • BLOB Fields: Stored directly within table rows in SQL. To read or write, call Record.BlobField.CreateInStream(InStream) or Record.BlobField.CreateOutStream(OutStream).
  • Media & MediaSet Data Types: Modern alternatives to table BLOBs. Instead of storing large binary blobs inside the transactional business table, Media stores images and attachments in a dedicated system table (Tenant Media), referencing them via a unique MediaId (GUID). This keeps business tables lightweight and optimizes database performance.
Loading diagram...
Cloud Stream Lifecycle, TempBlob Buffering & Base64 REST Pipeline

3. Cloud File Management: UploadIntoStream & DownloadFromStream

In Business Central SaaS environments ("target": "Cloud"), AL code cannot access local drives (C:\) or physical network shares. Attempting to use the native File data type or .NET file I/O triggers compilation errors. File interactions must be handled through client-side stream dialogs or cloud storage APIs.

local procedure ExportSalesLedgerCsv()
var
    CustLedgEntry: Record "Cust. Ledger Entry";
    TempBlob: Codeunit "Temp Blob";
    ExportOutStream: OutStream;
    ExportInStream: InStream;
    ClientFileName: Text;
begin
    // 1. Build CSV content into TempBlob OutStream
    TempBlob.CreateOutStream(ExportOutStream, TextEncoding::UTF8);
    ExportOutStream.WriteText('EntryNo,PostingDate,CustomerNo,Amount');
    ExportOutStream.WriteText();

    if CustLedgEntry.FindSet() then
        repeat
            ExportOutStream.WriteText(StrSubstNo('%1,%2,%3,%4',
                CustLedgEntry."Entry No.",
                CustLedgEntry."Posting Date",
                CustLedgEntry."Customer No.",
                CustLedgEntry.Amount));
            ExportOutStream.WriteText();
        until CustLedgEntry.Next() = 0;

    // 2. Deliver the InStream to the user's web browser
    TempBlob.CreateInStream(ExportInStream);
    ClientFileName := 'CustomerLedgerExport.csv';
    DownloadFromStream(ExportInStream, 'Download Export', '', 'CSV Files (*.csv)|*.csv', ClientFileName);
end;

local procedure ImportFileFromUser()
var
    UploadInStream: InStream;
    DialogTitle: Text;
    FromFileName: Text;
begin
    DialogTitle := 'Select XML Document to Import';
    // Upload from client machine directly into an InStream
    if UploadIntoStream(DialogTitle, '', 'XML Files (*.xml)|*.xml', FromFileName, UploadInStream) then begin
        Message('Successfully uploaded file: %1', FromFileName);
        // Parse UploadInStream with XmlDocument or XMLport
    end;
end;

Core Client-Server File Transfer APIs

  • UploadIntoStream(DialogTitle, FromFolder, FromFilter, FromFile, InStream): Displays a file picker dialog in the web browser. The uploaded file content is streamed directly into the provided InStream variable.
  • DownloadFromStream(InStream, DialogTitle, ToFolder, ToFilter, ToFile): Streams data from the Business Central Server to the user's web browser, triggering the browser's native file download workflow.
  • Codeunit 419 "File Management": Contains high-level helper routines, such as extracting file extensions (GetExtension), resolving MIME types (GetMimeType), extracting file names (GetFileName), and converting files to temporary server paths when running in on-premises environments.

4. Base64 Encoding & REST API Payload Integration

Web services and RESTful APIs commonly transmit binary files (PDFs, images, spreadsheets) as Base64-encoded strings embedded within JSON or XML payloads. Business Central provides Codeunit 4114 "Base64 Convert" to perform bidirectional conversion.

local procedure BuildJsonPayloadWithPdfAttachment(var PdfInStream: InStream): Text
var
    Base64Convert: Codeunit "Base64 Convert";
    JsonObjectPayload: JsonObject;
    Base64PdfString: Text;
    SerializedJson: Text;
begin
    // Convert binary InStream directly to Base64 Text
    Base64PdfString := Base64Convert.ToBase64(PdfInStream);

    // Embed into JSON Object
    JsonObjectPayload.Add('documentType', 'Invoice');
    JsonObjectPayload.Add('mimeType', 'application/pdf');
    JsonObjectPayload.Add('payloadBase64', Base64PdfString);

    JsonObjectPayload.WriteTo(SerializedJson);
    exit(SerializedJson);
end;

local procedure DecodeBase64PayloadToTempBlob(Base64Content: Text; var TempBlob: Codeunit "Temp Blob")
var
    Base64Convert: Codeunit "Base64 Convert";
    TargetOutStream: OutStream;
begin
    TempBlob.CreateOutStream(TargetOutStream);
    // Decode Base64 string directly into the OutStream
    Base64Convert.FromBase64(Base64Content, TargetOutStream);
end;

Base64 Convert Method Overloads

  • ToBase64(InStream): Reads bytes from an InStream and returns a Base64-encoded Text string.
  • ToBase64(Text): Converts an unencoded string to its Base64 representation.
  • FromBase64(Base64Text, OutStream): Decodes a Base64 string and streams the raw binary bytes directly into the target OutStream.
  • FromBase64(Base64Text): Decodes a Base64 string back into plain Text.
Test Your Knowledge

A developer is migrating a legacy C/AL report to AL for a Business Central SaaS deployment. The legacy code contains: ServerFile.Create('C:\Exports\Output.txt'); ServerFile.Write(ExportData); ServerFile.Close();. How must this logic be refactored to comply with Cloud development requirements?

A
B
C
D
Test Your Knowledge

An AL procedure needs to read a binary image uploaded by a user and store it in an in-memory buffer to verify its byte length before saving. Which sequence of TempBlob operations correctly accomplishes this?

A
B
C
D
Test Your Knowledge

An AL integration routine receives a JSON object from an external logistics API containing a Base64-encoded packing slip PDF string in a property named 'pdfData'. Which codeunit and method should be used to convert this string into binary bytes for storage?

A
B
C
D
Test Your Knowledge

When reading structured lines from a text stream using InStream.ReadText(LineContent), how does the InStream determine when a single line ends, and how is the end of the entire stream detected?

A
B
C
D