20.3.2 數(shù)據(jù)庫BLOB字段應(yīng)用
Delphi VCL提供了TBlobStream對象支持對數(shù)據(jù)庫BLOB字段的存取。Delphi 的TBlobStream對象的作用在于一方面可以使Delphi應(yīng)用程序充分利用多媒體數(shù)據(jù)庫的數(shù)據(jù)管理能力。另一方面又能利用Delphi Object Pascal的程序設(shè)計能力給關(guān)系型多媒體數(shù)據(jù)庫提供底層控制能力和全方位的功能擴展余地。
20.3.2.1 TBlobStream的使用
TBlobStream對象用一個TBlobField類型的對象作為參數(shù)來創(chuàng)建與BLOB字段相聯(lián)的BLOB流,接著就可用流的存取方法在BLOB字段中存取數(shù)據(jù)。
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]);
{ 寫相應(yīng)媒體擴展信息 }
……
end;
WriteListEnd;
finally.
Free;
end;
BlobStream.Free;
CardTable.Post;
end;
Fields變量是表示數(shù)據(jù)庫記錄的字段數(shù)組,F(xiàn)ields[10]正是數(shù)據(jù)庫的BLOB 字段。CardTable的Post方法將數(shù)據(jù)庫的修改反饋到數(shù)據(jù)庫的物理存儲上。
上面這段程序是超媒體卡片存儲的部分源程序,我們就是將卡片保存在數(shù)據(jù)庫BLOB字段中,實現(xiàn)將超文本和關(guān)系數(shù)據(jù)庫兩種數(shù)據(jù)管理方式結(jié)合起來。讀卡片的程序如下:
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字段與圖形圖像
在多媒體數(shù)據(jù)庫中處理得比較多的是圖形圖像,因此早期的多媒體數(shù)據(jù)庫在擴展關(guān)系數(shù)據(jù)庫時往往是增加一個圖像字段。BLOB字段是以二進制數(shù)據(jù)存儲方式,因此它完全可以表達圖形圖像數(shù)據(jù)。
在TBlobField對象中提供了LoadFromBitMap和SaveToBitMap方法存取位圖數(shù)據(jù)。它們在實現(xiàn)上都是使用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;
程序中按兩種方式存取數(shù)據(jù),對于位圖數(shù)據(jù),數(shù)據(jù)的起點是流的Potition為0處,對于圖形或其它類型的Blob數(shù)據(jù),則以流的Position為SizeOf(Header) + 1處開始, 即多了個頭信息。
Delphi VCL提供了TBlobStream對象支持對數(shù)據(jù)庫BLOB字段的存取。Delphi 的TBlobStream對象的作用在于一方面可以使Delphi應(yīng)用程序充分利用多媒體數(shù)據(jù)庫的數(shù)據(jù)管理能力。另一方面又能利用Delphi Object Pascal的程序設(shè)計能力給關(guān)系型多媒體數(shù)據(jù)庫提供底層控制能力和全方位的功能擴展余地。
20.3.2.1 TBlobStream的使用
TBlobStream對象用一個TBlobField類型的對象作為參數(shù)來創(chuàng)建與BLOB字段相聯(lián)的BLOB流,接著就可用流的存取方法在BLOB字段中存取數(shù)據(jù)。
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]);
{ 寫相應(yīng)媒體擴展信息 }
……
end;
WriteListEnd;
finally.
Free;
end;
BlobStream.Free;
CardTable.Post;
end;
Fields變量是表示數(shù)據(jù)庫記錄的字段數(shù)組,F(xiàn)ields[10]正是數(shù)據(jù)庫的BLOB 字段。CardTable的Post方法將數(shù)據(jù)庫的修改反饋到數(shù)據(jù)庫的物理存儲上。
上面這段程序是超媒體卡片存儲的部分源程序,我們就是將卡片保存在數(shù)據(jù)庫BLOB字段中,實現(xiàn)將超文本和關(guān)系數(shù)據(jù)庫兩種數(shù)據(jù)管理方式結(jié)合起來。讀卡片的程序如下:
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字段與圖形圖像
在多媒體數(shù)據(jù)庫中處理得比較多的是圖形圖像,因此早期的多媒體數(shù)據(jù)庫在擴展關(guān)系數(shù)據(jù)庫時往往是增加一個圖像字段。BLOB字段是以二進制數(shù)據(jù)存儲方式,因此它完全可以表達圖形圖像數(shù)據(jù)。
在TBlobField對象中提供了LoadFromBitMap和SaveToBitMap方法存取位圖數(shù)據(jù)。它們在實現(xiàn)上都是使用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;
程序中按兩種方式存取數(shù)據(jù),對于位圖數(shù)據(jù),數(shù)據(jù)的起點是流的Potition為0處,對于圖形或其它類型的Blob數(shù)據(jù),則以流的Position為SizeOf(Header) + 1處開始, 即多了個頭信息。

