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