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.
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.
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.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.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;
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();.
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.
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.
CalcFields first.File.Create that fails on upgrade to cloud. Replace with the patterns above; target: Cloud catches it at compile time.