Read and write files by using streaming in Business Central

Completed

Streaming is an important concept in programming languages. In AL, you can access binary data that is stored in objects, such as files or BLOB fields, without consideration of the actual representation, capabilities, or limitations of the object in which the data is stored. In addition to accessing data in files or BLOBs, AL lets you stream data directly from and into Business Central by using XMLports and the HttpClient data type.

You can read from or write to streams by using the InStream and OutStream methods. The Temp Blob codeunit can be used to convert between the two stream types.

The InStream data type can be used to read bytes from a stream object. The data is read in binary format, and you can use the Read and ReadText functions to read that format.

var
    InStr: InStream;
    FileName: Text;
    NumberOfBytesRead: Integer;
    TextRead: Text;
begin
    if(File.UploadIntoStream('Open File','','All Files (*.*)|*.*', 
                             FileName, InStr)) then begin 
        while not InStr.EOS() do begin
            NumberOfBytesRead := InStr.ReadText(TextRead, 100);
            Message('%1\Size: %2', TextRead, NumberOfBytesRead);
        end;
    end;
end;

The OutStream data type can be used to write bytes to a stream object. The data is written in binary format, and you can use the Write and WriteText functions to write to that format.

var
    OutStr: OutStream;
    MyTable: Record MyTable;
begin
    if (MyTable.FindFirst()) then begin 
        MyTable.Data.CreateOutStream(OutStr);
        OutStr.WriteText('<html>');
        OutStr.WriteText('<body>');
        OutStr.WriteText('<h1>AL Language in Business Central is awesome!</h1>');
        OutStr.WriteText('</body>');
        OutStr.WriteText('</html>');
    end;
end;

You can use the streaming functions to upload and download images from Business Central. The Media and MediaSet data types support the use of InStream data types. The following code example shows how you can use the Picture field (data type MediaSet) of the Customer table to store images through the streaming functions.

    local procedure ChangeCustomerPicture(Customer : Record Customer)
    var
        CustomerInStream : InStream;
        ImageFilter : Text;
    begin
        ImageFilter := 'Image Files (*.bmp;*.jpg;*.gif)|*.bmp;*.jpg;*.gif';
        
        if not UploadIntoStream(ImageFilter, CustomerInStream) then
            exit;

        Customer.Image.ImportStream(CustomerInStream,'Customer Picture');
    end; 

To export images, you can use the DownloadFromStream function. The following code example shows all images in a certain MediaSet that will be downloaded. The user will get a prompt for each image to download.

    local procedure DownloadCustomerPicture(Customer : Record Customer)
    var
        TempBlob : Codeunit "Temp Blob";
        CustomerOutStream : OutStream;
        CustomerInStream : InStream;
        ImageFilter, FileName : Text;
    begin
        TempBlob.CreateOutStream(CustomerOutStream);
        Customer.Image.ExportStream(CustomerOutStream);
        TempBlob.CreateInStream(CustomerInStream);

        ImageFilter := 'Image Files (*.bmp;*.jpg;*.gif)|*.bmp;*.jpg;*.gif';
        FileName := 'Customer Picture';

        if not DownloadFromStream(CustomerInStream,'Download Customer Picture','',ImageFilter, FileName) then
            exit;
    end;