20.3.2 數據庫BLOB字段應用
Delphi VCL提供了TBlobStream對象支持對數據庫BLOB字段的存取。Delphi 的TBlobStream對象的作用在於一方面可以使Delphi應用程序充分利用多媒體數據庫的數據管理能力。另一方面又能利用Delphi Object Pascal的程序設計能力給關系型多媒體數據庫提供底層控制能力和全方位的功能擴展余地。
20.3.2.1 TBlobStream的使用
TBlobStream對象用一個TBlobField類型的對象作為參數來創建與BLOB字段相聯的BLOB流,接著就可用流的存取方法在BLOB字段中存取數據。
var
BlobStream: TBlobStream;
I: Integer;
begin
BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10], bmWrite);
With TWriter.Create(BlobStream, 4096) do
try
for I := 0 to DesignWin.ControlCount - 1 do
begin
WriteInteger(MMID[i]);
WriteRootComponent(DesignWin.Controls[i]);
{ 寫相應媒體擴展信息 }
……
end;
WriteListEnd;
finally.
Free;
end;
BlobStream.Free;
CardTable.Post;
end;
Fields變量是表示數據庫記錄的字段數組,Fields[10]正是數據庫的BLOB 字段。CardTable的Post方法將數據庫的修改反饋到數據庫的物理存儲上。
上面這段程序是超媒體卡片存儲的部分源程序,我們就是將卡片保存在數據庫BLOB字段中,實現將超文本和關系數據庫兩種數據管理方式結合起來。讀卡片的程序如下:
var
PropInfo: PPropInfo;
Method: TMethod;
Blobtream: TStream;
I: Integer;
begin
BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10]), bmRead);
With TReader.Create(BlobStream, 4096) do
try
while not EndOfList do
begin
case ReadInteger of
IDText: begin
Ctrl := TControl(ReadRootComponent(nil));
PropInfo := GetPropInfo(Ctrl.ClassInfo, 'OnClick');
Method.Code:= Self.MethodAddress(MethodName);
Method.Data := Self;
if Method.Code <> nil then
SetMethodProp(Ctrl, PropInfo, Method);
DesignWin.InsertControl(Ctrl);
end;
IDImage:
……
end;
……
WriteListEnd;
end;
finally.
Free;
end;
FileStream.Free;
end;
20.3.2.2 BLOB字段與圖形圖像
在多媒體數據庫中處理得比較多的是圖形圖像,因此早期的多媒體數據庫在擴展關系數據庫時往往是增加一個圖像字段。BLOB字段是以二進制數據存儲方式,因此它完全可以表達圖形圖像數據。
在TBlobField對象中提供了LoadFromBitMap和SaveToBitMap方法存取位圖數據。它們在實現上都是使用BlobStream對象。
procedure TBlobField.LoadFromBitmap(Bitmap: TBitmap);
var
BlobStream: TBlobStream;
Header: TGraphicHeader;
begin
BlobStream := TBlobStream.Create(Self, bmWrite);
try
if (DataType = ftGraphic) or (DataType = ftTypedBinary) then
begin
Header.Count := 1;
Header.HType := $0100;
Header.Size := 0;
BlobStream.Write(Header, SizeOf(Header));
Bitmap.SaveToStream(BlobStream);
Header.Size := BlobStream.Position - SizeOf(Header);
BlobStream.Position := 0;
BlobStream.Write(Header, SizeOf(Header));
end else
Bitmap.SaveToStream(BlobStream);
finally
BlobStream.Free;
end;
end;
procedure TBlobField.SaveToBitmap(Bitmap: TBitmap);
var
BlobStream: TBlobStream;
Size: Longint;
Header: TGraphicHeader;
begin
BlobStream := TBlobStream.Create(Self, bmRead);
try
Size := BlobStream.Size;
if Size >= SizeOf(TGraphicHeader) then
begin
BlobStream.Read(Header, SizeOf(Header));
if (Header.Count <> 1) or (Header.HType <> $0100) or
(Header.Size <> Size - SizeOf(Header)) then
BlobStream.Position := 0;
end;
Bitmap.LoadFromStream(BlobStream);
finally
BlobStream.Free;
end;
end;
程序中按兩種方式存取數據,對於位圖數據,數據的起點是流的Potition為0處,對於圖形或其它類型的Blob數據,則以流的Position為SizeOf(Header) + 1處開始, 即多了個頭信息。
20.3.2.3 BLOB字段與文本
Delphi BLOB字段中增加了大型文本的處理能力。可以在TBlobField和Strings中自由地交換數據。
procedure TBlobField.LoadFromStrings(Strings: TStrings);
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream.Create(Self, bmWrite);
try
Strings.SaveToStream(BlobStream);
finally
BlobStream.Free;
end;
end;
procedure TBlobField.SaveToStrings(Strings: TStrings);
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream.Create(Self, bmRead);
try
Strings.LoadFromStream(BlobStream);
finally
BlobStream.Free;
end;
end;