熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

DELPHI基礎教程:開發Delphi對象式數據管理功能(二)[3]

2013-11-23 17:47:58  來源: Delphi編程 

  方法中用到的DbiOpenBlob函數是BDE的API函數該函數用於打開數據庫中的BLOB字段

  最後如果方法傳入的Mode參數值為bmWrite就調用Truncate將當前位置指針以後的

  數據刪除

  分析這段源程序不難知道

  ● 讀寫BLOB字段不允許BLOB字段所在DataSet部件有Filter否則產生異常事件

  ● 要讀寫BLOB字段必須將DataSet設為編輯或插入狀態

  ● 如果BLOB字段中的數據作了修改則在創建BLOB 流時不再重新調用DBiOpenBlob函數而只是簡單地將FOpened置為True這樣可以用多個BLOB 流對同一個BLOB字段讀寫

  Destroy方法釋放BLOB字段和為FBuffer分配的緩沖區其實現如下

  destructor TBlobStreamDestroy;

  begin

  if FOpened then

  begin

  if FModified then FFieldFModified := True;

  if not FFieldFModified then

  DbiFreeBlob(FDataSetHandle FRecord FFieldNo)

  end;

  if FBuffer <> nil then FreeMem(FBuffer FDataSetRecordSize)

  if FModified then

  try

  FFieldDataChanged;

  except

  ApplicationHandleException(Self)

  end;

  end;

  如果BLOB流中的數據作了修改就將FField的FModified置為True;如果FField的Modified為False就釋放BLOB字段如果FBuffer不為空則釋放臨時內存最後根據FModified的值來決定是否啟動FField的事件處理過程DataChanged

  不難看出如果BLOB字段作了修改就不釋放BLOB字段並且對BLOB 字段的修改只有到Destroy時才提交這是因為讀寫BLOB字段時都避開了FField而直接調用BDE API函數這一點是在應用BDE API編程中很重要即一定要修改相應數據庫部件的狀態

   Read和Write方法的實現

  Read和Write方法都調用BDE API函數完成數據庫BLOB字段的讀寫其實現如下

  function TBlobStreamRead(var Buffer; Count: Longint) Longint;

  var

  Status: DBIResult;

  begin

  Result := ;

  if FOpened then

  begin

  Status := DbiGetBlob(FDataSetHandle FRecord FFieldNo FPosition

  Count @Buffer Result)

  case Status of

  DBIERR_NONE DBIERR_ENDOFBLOB:

  begin

  if FFieldFTransliterate then

  NativeToAnsiBuf(FDataSetLocale @Buffer @Buffer Result)

  Inc(FPosition Result)

  end;

  DBIERR_INVALIDBLOBOFFSET:

  {Nothing};

  else

  DbiError(Status)

  end;

  end;

  end;

  Read方法使用了BDE API的DbiGetBlob函數從FDataSet中讀取數據在本函數中各參數的含義是這樣的FDataSetHandle代表DataSet的BDE句柄FReacord表示BLOB字段所在記錄FFieldNo表示BLOB字段號FPosition表示要讀的的數據的起始位置Count表示要讀的字節數Buffer是讀出數據所占的內存Result是實際讀出的字節數該BDE函數返回函數調用的錯誤狀態信息

  Read方法還調用了NativeToAnsiBuf進行字符集的轉換

  function TBlobStreamWrite(const Buffer; Count: Longint) Longint;

  var

  Temp: Pointer;

  begin

  Result := ;

  if FOpened then

  begin

  if FFieldFTransliterate then

  begin

  GetMem(Temp Count)

  try

  AnsiToNativeBuf(FDataSetLocale @Buffer Temp Count)

  Check(DbiPutBlob(FDataSetHandle FRecord FFieldNo FPosition

  Count Temp))

  finally

  FreeMem(Temp Count)

  end;

  end else

  Check(DbiPutBlob(FDataSetHandle FRecord FFieldNo FPosition

  Count @Buffer))

  Inc(FPosition Count)

  Result := Count;

  FModified := True;

  end;

  end;

  Write方法調用了BDE API的DbiPutBlob函數實現往數據庫BLOB字段存儲數據

  該函數的各參數含義如下

  表 調用函數DbiPutBlob的各傳入參數的含義

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  參數名           含義

  ──────────────────────────────

  FDataSetHandle 寫入的數據庫的BDE句柄

  FRecord 寫入數據的BLOB字段所在的記錄

  FFieldNo BLOB字段號

  FPosition 寫入的起始位置

  Count 寫入的數據的字節數

  Buffer 所寫入的數據占有的內存地址

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  方法中還根據FField和FTransliterate的值判斷是否進行相應的字符集轉換最後移動BLOB流的位置指針並將修改標志FModified置為True

   Seek和GetBlobSize方法的實現

  Seek方法的功能主要是移動BLOB流的位置指針GetBlobSize方法是私有的在Seek方法中被調用其功能是得到BLOB數據的大小它們的實現如下

  function TBlobStreamGetBlobSize: Longint;

  begin

  Result := ;

  if FOpened then

  Check(DbiGetBlobSize(FDataSetHandle FRecord FFieldNo Result))

  end;

  function TBlobStreamSeek(Offset: Longint; Origin: Word) Longint;

  begin

  case Origin of

  : FPosition := Offset;

  : Inc(FPosition Offset)

  : FPosition := GetBlobSize + Offset;

  end;

  Result := FPosition;

  end;

  GetBlobSize調用了BDE API的DbiGetBlobSize函數該函數的參數的含義同前面的API函數相同

[]  []  []  []  


From:http://tw.wingwit.com/Article/program/Delphi/201311/25102.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.