2. Read和Write方法的實現
Read和Write方法都調用BDE API函數完成數據庫BLOB字段的讀寫,其實現如下:
function TBlobStream.Read(var Buffer; Count: Longint): Longint;
var
Status: DBIResult;
begin
Result := 0;
if FOpened then
begin
Status := DbiGetBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, @Buffer, Result);
case Status of
DBIERR_NONE, DBIERR_ENDOFBLOB:
begin
if FField.FTransliterate then
NativeToAnsiBuf(FDataSet.Locale, @Buffer, @Buffer, Result);
Inc(FPosition, Result);
end;
DBIERR_INVALIDBLOBOFFSET:
{Nothing};
else
DbiError(Status);
end;
end;
end;
Read方法使用了BDE API的DbiGetBlob函數從FDataSet中讀取數據,在本函數中,各參數的含義是這樣的:FDataSet.Handle代表DataSet的BDE句柄,FReacord表示BLOB字段所在記錄,FFieldNo表示BLOB字段號,FPosition表示要讀的的數據的起始位置,Count表示要讀的字節數,Buffer是讀出數據所占的內存,Result是實際讀出的字節數。該BDE函數返回函數調用的錯誤狀態信息。
Read方法還調用了NativeToAnsiBuf進行字符集的轉換。
function TBlobStream.Write(const Buffer; Count: Longint): Longint;
var
Temp: Pointer;
begin
Result := 0;
if FOpened then
begin
if FField.FTransliterate then
begin
GetMem(Temp, Count);
try
AnsiToNativeBuf(FDataSet.Locale, @Buffer, Temp, Count);
Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, Temp));
finally
FreeMem(Temp, Count);
end;
end else
Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, @Buffer));
Inc(FPosition, Count);
Result := Count;
FModified := True;
end;
end;
Write方法調用了BDE API的DbiPutBlob函數實現往數據庫BLOB字段存儲數據。
該函數的各參數含義如下:
表20.2 調用函數DbiPutBlob的各傳入參數的含義
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
參數名 含義
──────────────────────────────
FDataSetHandle 寫入的數據庫的BDE句柄
FRecord 寫入數據的BLOB字段所在的記錄
FFieldNo BLOB字段號
FPosition 寫入的起始位置
Count 寫入的數據的字節數
Buffer 所寫入的數據占有的內存地址
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
方法中還根據FField和FTransliterate的值判斷是否進行相應的字符集轉換,最後移動BLOB流的位置指針,並將修改標志FModified置為True。
3. Seek和GetBlobSize方法的實現
Seek方法的功能主要是移動BLOB流的位置指針。GetBlobSize方法是私有的,在Seek方法中被調用,其功能是得到BLOB數據的大小。它們的實現如下:
function TBlobStream.GetBlobSize: Longint;
begin
Result := 0;
if FOpened then
Check(DbiGetBlobSize(FDataSet.Handle, FRecord, FFieldNo, Result));
end;
function TBlobStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
case Origin of
0: FPosition := Offset;
1: Inc(FPosition, Offset);
2: FPosition := GetBlobSize + Offset;
end;
Result := FPosition;
end;
GetBlobSize調用了BDE API的DbiGetBlobSize函數,該函數的參數的含義同前面的API函數相同。