Email this post as a PDFDevelopment · 1 October 2026 · 2 min read

Files, streams and Temp Blob: handling binary data in AL

AL has no file system in the cloud, so everything that used to be a file is a stream. InStream and OutStream, the Temp Blob codeunit, uploading from and downloading to the browser, Base64, and storing files in Blob versus Media fields. The patterns, with code, and the three errors everyone hits once.

Contents
  1. The pieces
  2. Download a generated file
  3. Upload and store
  4. Base64 and HTTP
  5. Text encoding
  6. The three errors

In NAV you wrote a file to a path. In Business Central online there is no path. There are streams, there is a temporary blob you can write to and read from, and there is a browser on the other end that can upload and download. Once you think in those terms the whole area is small.

The pieces

  • InStream / OutStream: read-from and write-to handles. You get them from a Blob field, a Temp Blob, a Media field, an HTTP response, or the upload/download functions.
  • Codeunit "Temp Blob": an in-memory blob with CreateOutStream, CreateInStream, HasValue, Length. The standard way to hold a file while you work on it.
  • Blob field on a table: persistent binary, loaded only on CalcFields. Fine for a document per record. Media / MediaSet fields: platform-managed storage for images and files, deduplicated, served to the client efficiently, with ImportStream/ExportStream. Prefer Media for anything the client displays.
  • File.UploadIntoStream and File.DownloadFromStream: the only file dialogs in the cloud; they talk to the user's browser.

Download a generated file

procedure DownloadCsv()
var
    TempBlob: Codeunit "Temp Blob";
    OutStr: OutStream;
    InStr: InStream;
    FileName: Text;
begin
    TempBlob.CreateOutStream(OutStr, TextEncoding::UTF8);
    OutStr.WriteText(HeaderLineTxt);
    OutStr.WriteText();  // newline
    // ... write rows
    TempBlob.CreateInStream(InStr, TextEncoding::UTF8);
    FileName := StrSubstNo(FileNameTok, Format(Today(), 0, 9));
    DownloadFromStream(InStr, '', '', '', FileName);
end;

Upload and store

procedure UploadAttachment(var Shipment: Record "CON Courier Shipment")
var
    InStr: InStream;
    FileName: Text;
begin
    if not UploadIntoStream(SelectFileLbl, '', '', FileName, InStr) then
        exit;
    Shipment.Label.ImportStream(InStr, FileName);   // Label is a Media field
    Shipment.Modify(true);
end;

For a Blob field instead: Shipment.Document.CreateOutStream(OutStr); CopyStream(OutStr, InStr); Shipment.Modify();.

Base64 and HTTP

APIs often want files as Base64 text. Codeunit "Base64 Convert" has ToBase64(InStream) and FromBase64(Text, OutStream). An HTTP response gives you Response.Content().ReadAs(InStream) for binary bodies (a PDF label from a courier), which you then write to Temp Blob or a Media field. The HttpClient post covers the call.

Text encoding

Pass TextEncoding::UTF8 when creating streams for text, and UTF8 with BOM awareness when reading files from Windows systems. The default (MSDos) is why imported CSVs show accented characters as nonsense.

The three errors

  • "The stream is not readable/writable": you created an OutStream and tried to read it, or read a Blob field without CalcFields first.
  • Empty file: you wrote to the OutStream after creating the InStream. Write everything, then create the InStream.
  • On-premise code using File.Create that fails on upgrade to cloud. Replace with the patterns above; target: Cloud catches it at compile time.
Email this post as a PDF
A branded PDF of this post, sent to your inbox to keep, print or share. Copy in colleagues if you like.
We only use these addresses to send this PDF. Nobody is added to a mailing list. Mike at Business Boxed receives a copy. See our privacy notice.
Email this post
Talk to us
Want this done in your Business Central?
Book a 30 minute callGet the monthly newsletter

Related posts