In most file oriented databases (such as dBase, FoxPro, Paradox)
 
 Creating Blobs 
CREATE TABLE "DataCollection" ( "ID" VARCHAR( 5), "Barcode" VARCHAR(15), "DateTime" TIMESTAMP, "DataArray" BLOB /* SUB_TYPE 1 */ );
 
 Reading Blobs 
var
  Stream  : TMemoryStream;
  bf      : TBlobField;
  AnArray : array[1..5000] of single; // A buffer to hold the data
begin
  bf := Data_IBTable.FieldByName(Field) as TBlobField;
  Stream := TMemoryStream.Create;
  try
    bf.SaveToStream(Stream);
    ArraySize  := high(AnArray) * SizeOf(single);  // compute the maximum number of bytes to copy
    Stream.Position :=0;             // after loading stream, *position* is the last byte
    Stream.Read(AnArray, ArraySize); // copy up to "ArraySize" bytes to array
  finally
    Stream.Free;
  end;
These next 2 are based on the Delphi help
var
  Stream : TBlobStream;
begin
  Stream := TBlobStream.Create(BlobFieldObject, bmRead);
  try
    // use the stream here
  finally
    Stream.Free;
  end;
In many ways, this is the simplest example because you don't have to explicitly cast the field
var
  Stream : TBlobStream;
begin
  Stream := Table2.CreateBlobStream(Table2.FieldByName('Comments'), bmReadWrite);
  try
    // use the stream here
  finally
    Stream.Free;
  end;
 
 Reading Blobs - Example 
In one project, the contents of an array is stored in a blob field. The size of the array is data dependent and varies from record to record.
The IBTable_Extensions unit adds several methods to TIBTable and TIBQuery - the only method shown here is BlobToArrayOfSingle.
Type
   TValues = array[1..MaxPts] of single;
   PValues = ^TValues;
  TExtended_IBTable = class(TIBTable)
    procedure BlobToArrayOfSingle(Field: string; var AnArray: array of single);
  end;
  TExtended_IBQuery = class(TIBQuery)
    procedure BlobToArrayOfSingle(Field: string; var AnArray: array of single);
  end;
var
   Yvalues      : array [0..17] of PValues ; // an array of pointers to arrays of single
   DataSetToUse : TExtended_IBQuery        ;
begin  // some method
   DataSetToUse.BlobToArrayOfSingle('SPECTRUM_Y', YValues^);
end
procedure TExtended_IBTable.BlobToArrayOfSingle(Field: string; var AnArray: array of single);
var
//AnArray    : array[1..5000] of single; // Just a comment on the expected format of this parameter
  bf         : TBlobField;
//StreamSize : integer;
  ArraySize  : integer;
  Stream     : TMemoryStream;
begin
  bf := self.FieldByName(Field) as TBlobField;
  Stream := TMemoryStream.Create;
  try
    bf.SaveToStream(Stream);
//  StreamSize := Stream.Size; // just for debug
    ArraySize  := high(AnArray) * SizeOf(single);  // compute the maximum number of bytes to copy
    Stream.Position :=0; // after loading stream, *position* is the last byte
    Stream.Read(AnArray, ArraySize); // copy up to "ArraySize" bytes to array
  finally
    Stream.Free;
  end;
end;
 
 Writing Blobs 
var
 Stream : TStream ; // TBlobStream does not work
 ar1 : tArrayOfSingle;
begin
  Spectra_IBTable.Active := true;
  Spectra_IBTable.Insert;
  Spectra_IBTable.FieldByName('TYPE_NUM').AsInteger := Spectra_Type_int;
  Stream := Spectra_IBTable.CreateBlobStream(Spectra_IBTable.FieldByName('SPECTRUM_y'), bmWrite);
  try
    // use the stream here
    ar1 := JCAMP_1.YData_Pointer;
    Stream.Write(ar1[0], JCAMP_1.ArrayLength * SizeOf(single) );
    Spectra_IBTable.Post;
  finally
    Stream.Free;  // free the stream for each record
  end;
This code fails
    Stream.Write(ar1, JCAMP_1.ArrayLength * SizeOf(single) );
Don't forget the array index!
Author: Robert Clemenzi -
clemenzi@cpcug.org