首頁(yè) 考試吧論壇 Exam8視線 考試商城 網(wǎng)絡(luò)課程 模擬考試 考友錄 實(shí)用文檔 求職招聘 論文下載
2011中考 | 2011高考 | 2012考研 | 考研培訓(xùn) | 在職研 | 自學(xué)考試 | 成人高考 | 法律碩士 | MBA考試
MPA考試 | 中科院
四六級(jí) | 職稱(chēng)英語(yǔ) | 商務(wù)英語(yǔ) | 公共英語(yǔ) | 托福 | 雅思 | 專(zhuān)四專(zhuān)八 | 口譯筆譯 | 博思 | GRE GMAT
新概念英語(yǔ) | 成人英語(yǔ)三級(jí) | 申碩英語(yǔ) | 攻碩英語(yǔ) | 職稱(chēng)日語(yǔ) | 日語(yǔ)學(xué)習(xí) | 法語(yǔ) | 德語(yǔ) | 韓語(yǔ)
計(jì)算機(jī)等級(jí)考試 | 軟件水平考試 | 職稱(chēng)計(jì)算機(jī) | 微軟認(rèn)證 | 思科認(rèn)證 | Oracle認(rèn)證 | Linux認(rèn)證
華為認(rèn)證 | Java認(rèn)證
公務(wù)員 | 報(bào)關(guān)員 | 銀行從業(yè)資格 | 證券從業(yè)資格 | 期貨從業(yè)資格 | 司法考試 | 法律顧問(wèn) | 導(dǎo)游資格
報(bào)檢員 | 教師資格 | 社會(huì)工作者 | 外銷(xiāo)員 | 國(guó)際商務(wù)師 | 跟單員 | 單證員 | 物流師 | 價(jià)格鑒證師
人力資源 | 管理咨詢(xún)師考試 | 秘書(shū)資格 | 心理咨詢(xún)師考試 | 出版專(zhuān)業(yè)資格 | 廣告師職業(yè)水平
駕駛員 | 網(wǎng)絡(luò)編輯
衛(wèi)生資格 | 執(zhí)業(yè)醫(yī)師 | 執(zhí)業(yè)藥師 | 執(zhí)業(yè)護(hù)士
會(huì)計(jì)從業(yè)資格考試會(huì)計(jì)證) | 經(jīng)濟(jì)師 | 會(huì)計(jì)職稱(chēng) | 注冊(cè)會(huì)計(jì)師 | 審計(jì)師 | 注冊(cè)稅務(wù)師
注冊(cè)資產(chǎn)評(píng)估師 | 高級(jí)會(huì)計(jì)師 | ACCA | 統(tǒng)計(jì)師 | 精算師 | 理財(cái)規(guī)劃師 | 國(guó)際內(nèi)審師
一級(jí)建造師 | 二級(jí)建造師 | 造價(jià)工程師 | 造價(jià)員 | 咨詢(xún)工程師 | 監(jiān)理工程師 | 安全工程師
質(zhì)量工程師 | 物業(yè)管理師 | 招標(biāo)師 | 結(jié)構(gòu)工程師 | 建筑師 | 房地產(chǎn)估價(jià)師 | 土地估價(jià)師 | 巖土師
設(shè)備監(jiān)理師 | 房地產(chǎn)經(jīng)紀(jì)人 | 投資項(xiàng)目管理師 | 土地登記代理人 | 環(huán)境影響評(píng)價(jià)師 | 環(huán)保工程師
城市規(guī)劃師 | 公路監(jiān)理師 | 公路造價(jià)師 | 安全評(píng)價(jià)師 | 電氣工程師 | 注冊(cè)測(cè)繪師 | 注冊(cè)計(jì)量師
繽紛校園 | 實(shí)用文檔 | 英語(yǔ)學(xué)習(xí) | 作文大全 | 求職招聘 | 論文下載 | 訪談 | 游戲

2011等考Delphi:開(kāi)發(fā)Delphi對(duì)象式數(shù)據(jù)管理功能

在本章中將介紹Stream對(duì)象和Filer對(duì)象的實(shí)現(xiàn)原理、應(yīng)用方法以及在超媒體系統(tǒng)中的應(yīng)用。這對(duì)于運(yùn)用Delphi 開(kāi)發(fā)高級(jí)應(yīng)用是很重要的。

  2. TMemoryStream對(duì)象方法的實(shí)現(xiàn)

  ⑴ Realloc方法

  Realloc方法是TMemoryStream動(dòng)態(tài)內(nèi)存分配的核心,它的SetSize、SetCapacity等方法最終都是調(diào)用Realloc進(jìn)行內(nèi)存的分配和初始化工作的。它的實(shí)現(xiàn)如下:

  const

  MemoryDelta = $2000;

  function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;

  begin

  if NewCapacity > 0 then

  NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);

  Result := Memory;

  if NewCapacity <> FCapacity then

  begin

  if NewCapacity = 0 then

  begin

  GlobalFreePtr(Memory);

  Result := nil;

  end else

  begin

  if Capacity = 0 then

  Result := GlobalAllocPtr(HeapAllocFlags, NewCapacity)

  else

  Result := GlobalReallocPtr(Memory, NewCapacity, HeapAllocFlags);

  if Result = nil then raise EStreamError.CreateRes(SMemoryStreamError);

  end;

  end;

  end;

  Realloc方法是以8K為單位分配動(dòng)態(tài)內(nèi)存的,方法中的第一句if語(yǔ)句就是執(zhí)行該操作。如果傳入的NewCapacity參數(shù)值為0,則釋放流中的內(nèi)存。Realloc方法用GLobal FreePtr函數(shù)釋放內(nèi)存,用GlobalAllocPtr分配內(nèi)存,用GlobalReallocPtr進(jìn)行內(nèi)存的重分配。如果原來(lái)的Capacity屬性值為0,則調(diào)用Globa|AllocPtr否則調(diào)用GlobalReallocPtr。最后如果Result為nil則觸發(fā)內(nèi)存流錯(cuò)的異常事件,否則返回指向分配的內(nèi)存的指針。

  ⑵ Write方法

  Write方法從內(nèi)存流內(nèi)部緩沖池的當(dāng)前位置開(kāi)始寫(xiě)入二進(jìn)制數(shù)據(jù)。其實(shí)現(xiàn)如下:

  function TMemoryStream.Write(const Buffer; Count: Longint): Longint;

  var

  Pos: Longint;

  begin

  if (FPosition >= 0) and (Count >= 0) then

  begin

  Pos := FPosition + Count;

  if Pos > 0 then

  begin

  if Pos > FSize then

  begin

  if Pos > FCapacity then

  SetCapacity(Pos);

  FSize := Pos;

  end;

  System.Move(Buffer, Pointer(Longint(FMemory) + FPosition)^, Count);

  FPosition := Pos;

  Result := Count;

  Exit;

  end;

  end;

  Result := 0;

  end;

  Buffer中存儲(chǔ)要寫(xiě)入流的二進(jìn)制數(shù)據(jù),如果要寫(xiě)入的數(shù)據(jù)的字節(jié)超出了流的內(nèi)存池的大小,則調(diào)用SetCapacity方法再分配內(nèi)存,然后用內(nèi)存復(fù)制函數(shù)將Buffer中的數(shù)據(jù)復(fù)制到FMemory中。接著移動(dòng)位置指針,并返回寫(xiě)入數(shù)據(jù)的字節(jié)數(shù)。分析這段程序可以知道,F(xiàn)Capacity的值和FSize的值是不同的。

  ⑶ Clear方法

  Clear方法消除內(nèi)存流中的數(shù)據(jù),將Memory屬性置為nil,并將FSize和FPosition 的值設(shè)為0。其實(shí)現(xiàn)如下:

  procedure TMemoryStream.Clear;

  begin

  SetCapacity(0);

  FSize := 0;

  FPosition := 0;

  end;

 、 LoadFromStream和LoadFromFile方法

  LoadFromStream方法首先根據(jù)傳入的Stream的Size屬性值重新分配動(dòng)態(tài)內(nèi)存,然后調(diào)用Stream的ReadBuffer方法往FMemory中復(fù)制數(shù)據(jù),結(jié)果Stream的全部?jī)?nèi)容在內(nèi)存中有了一份完整拷貝。其實(shí)現(xiàn)如下:

  procedure TMemoryStream.LoadFromStream(Stream: TStream);

  var

  Count: Longint;

  begin

  Stream.Position := 0;

  Count := Stream.Size;

  SetSize(Count);

  if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);

  end;

  LoadFromFile與LoadFromStream是一對(duì)方法。LoadFromFile首先創(chuàng)建了一個(gè)TFileStream對(duì)象,然后調(diào)用LoadFromStream方法,將FileStream文件流中的數(shù)據(jù)寫(xiě)入MemoryStream中。

  20.1.6 TResourceStream對(duì)象

  TResourceStream對(duì)象是另一類(lèi)MemoryStream對(duì)象,它提供對(duì)Windows 應(yīng)用程序資源的訪問(wèn),因此稱(chēng)它為資源流。TResourceSream也是從TCustomMemoryStream 繼承的。因此在TCustomMemoryStream對(duì)象的基礎(chǔ)上,定義了與指定資源模塊或資源文件建立連接的構(gòu)造方法,并且還覆蓋了Write,以實(shí)現(xiàn)向資源文件中寫(xiě)數(shù)據(jù)。

  下面介紹TResourceStream的實(shí)現(xiàn)

  1. 私有域

  TResourceStream沒(méi)有定義新的屬性,但它在private部分定義了兩個(gè)數(shù)據(jù)域HResInfo和HGlobol和一個(gè)私有方法Initialize,它們的定義如下:

  TResourceStream = class(TCustomMemoryStream)

  private

  HResInfo: HRSRC;

  HGlobal: THandle;

  procedure Initialize(Instance: THandle; Name, ResType: PChar);

  …

  end;

  HRSRC是描述Windows資源信息的結(jié)構(gòu)句柄。HGlobal變量代表資源所在模塊的句柄。如果操作的是應(yīng)用程序資源,HGlohal就代表EXE程序的句柄;如果是動(dòng)態(tài)鏈接庫(kù)(DLL),則HGlobal 代表動(dòng)態(tài)鏈接庫(kù)的句柄。TResourceStream對(duì)象使用這兩上變量訪問(wèn)應(yīng)用程序或動(dòng)態(tài)鏈接庫(kù)中的資源。

  Initialize方法是TResourceStream對(duì)象內(nèi)部使用的。它的構(gòu)造方法Create和CreateFromID都是調(diào)用Initialize方法完成對(duì)TResourceStream的初始化。它的實(shí)現(xiàn)如下:

  procedure TResourceStream.Initialize(Instance: THandle; Name, ResType: PChar);

  procedure Error;

  begin

  raise EResNotFound.Create(FmtLoadStr(SResNotFound, [Name]));

  end;

  begin

  HResInfo := FindResource(Instance, Name, ResType);

  if HResInfo = 0 then Error;

  HGlobal := LoadResource(Instance, HResInfo);

  if HGlobal = 0 then Error;

  SetPointer(LockResource(HGlobal), SizeOfResource(Instance, HResInfo));

  end;

  該方法實(shí)現(xiàn)中,首先調(diào)用Windows函數(shù)FoundResource得到由參數(shù)Instance指定的模塊中的名為Name和類(lèi)型為ResType的資源,然后調(diào)用LoadResource將資源調(diào)用內(nèi)存,并返回該資源在內(nèi)存中的句柄,最后,將該資源復(fù)制到ResourceStream中。方法的Instance參數(shù)代表要調(diào)用的資源所在的模塊句柄。模塊可以是可執(zhí)行文件,也可以是動(dòng)態(tài)鏈接庫(kù)。如果在讀取資源時(shí)沒(méi)在模塊中發(fā)現(xiàn)要找的資源則產(chǎn)生異常事件。

  2. 構(gòu)造方法Create和CreateFromID

  這兩個(gè)方法在實(shí)現(xiàn)上沒(méi)有大的不同。顧名思義,第一個(gè)方法是通過(guò)資源名構(gòu)造TResourceStream; 第二個(gè)方法通過(guò)資源ID構(gòu)造TResourceStream,而且在實(shí)現(xiàn)過(guò)程中,它們都調(diào)用了Initialize方法。下面是它們的實(shí)現(xiàn):

  constructor TResourceStream.Create(Instance: THandle; const ResName: string;

  ResType: PChar);

  begin

  inherited Create;

  Initialize(Instance, PChar(ResName), ResType);

  end;

  constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer;

  ResType: PChar);

  begin

  inherited Create;

  Initialize(Instance, PChar(ResID), ResType);

  end;

  這兩個(gè)方法中都有Instance參數(shù),該參數(shù)值的含義在Insitialize中介紹過(guò)。

  3. Write方法

  TResourceStream的Write方法只完成一件事,就產(chǎn)生這個(gè)異常事件,其實(shí)現(xiàn)如下:

  function TResourceStream.Write(const Buffer; Count: Longint): Longint;

  begin

  raise EStreamError.CreateRes(SCantWriteResourceStreamError);

  end;

  從方法實(shí)現(xiàn)中可以看到,TSourceStream對(duì)象是不允許寫(xiě)數(shù)據(jù)的。一旦往資源流中寫(xiě)數(shù)據(jù)將產(chǎn)生異常事件。

  4. 析構(gòu)方法Destroy

  該方法產(chǎn)生給資源解鎖,然后釋放該資源,最后調(diào)用繼承的Destroy方法釋放ResourceStream。其實(shí)現(xiàn)如下:

  destructor TResourceStream.Destroy;

  begin

  UnlockResource(HGlobal);

  FreeResource(HResInfo);

  inherited Destroy;

  end;

  回顧Initialize方法,我們不難發(fā)現(xiàn):

  ● ResourceStream沒(méi)有額外地給資源重新分配內(nèi)存,而是直接使用HGlobal句柄所指 的內(nèi)存域

  ● ResourceStream中的資源在流的生存期,始終是Lock狀態(tài),因此要根據(jù)Windows 的內(nèi)存使用規(guī)則合理安排ResourceStream的使用

  ● ResourceStream只是用于訪問(wèn)應(yīng)用程序和動(dòng)態(tài)鏈接庫(kù)中的資源的

  在Classes在單元中提供了InternalReadComponentRes函數(shù),該函數(shù)使用了TResourceStream對(duì)象從Delphi應(yīng)用程序中讀取部件。Delphi是將窗體和部件信息放在模塊資源的RCDATA段的。

  20.1.7 TBlobStream對(duì)象

  從Delphi 數(shù)據(jù)庫(kù)開(kāi)發(fā)平臺(tái)這個(gè)意義上說(shuō),TBlobStream 對(duì)象是個(gè)很重要的對(duì)象。TBlobStream對(duì)象提供了修改TBlobField、TBytesField或TVarBytesField中數(shù)據(jù)的技術(shù)。開(kāi)發(fā)者可以象對(duì)待文件或流那樣在數(shù)據(jù)庫(kù)域中讀寫(xiě)數(shù)據(jù)。

  傳統(tǒng)數(shù)據(jù)庫(kù)發(fā)展的一個(gè)重要趨向是往多媒體數(shù)據(jù)庫(kù)發(fā)展。目前比較著名和流行的數(shù)據(jù)庫(kù)都支持多媒體功能,多媒體數(shù)據(jù)存儲(chǔ)中的一大難點(diǎn)是數(shù)據(jù)結(jié)構(gòu)不規(guī)則,數(shù)據(jù)量大。各大數(shù)據(jù)庫(kù)產(chǎn)品是采用BLOB技術(shù)解決多媒體數(shù)據(jù)存儲(chǔ)中的問(wèn)題。Delphi的TBlobStream對(duì)象的意義就在于:一方面可以使Delphi應(yīng)用程序充分利用多媒體數(shù)據(jù)庫(kù)的數(shù)據(jù)管理能力;另一方面又能利用Object Pascal的強(qiáng)大程序設(shè)計(jì)能力給多媒體數(shù)據(jù)庫(kù)提供全方向的功能擴(kuò)展余地。

  使用TBlobStream對(duì)象可以在多媒體數(shù)據(jù)庫(kù)的BLOB字段存儲(chǔ)任意格式的數(shù)據(jù)。一般說(shuō)來(lái),許多多媒體數(shù)據(jù)庫(kù)只能支持圖像、語(yǔ)音或者OLE服務(wù)器支持的數(shù)據(jù)。利用TBlobStream則不同,只要是程序能夠定義的數(shù)據(jù)格式,它都能在BLOB字段中讀寫(xiě),而不需要其它輔助工具。

  TBlobStream用構(gòu)造方法Create建立數(shù)據(jù)庫(kù)域和BLOB流的聯(lián)接。用Read或Write 方法訪問(wèn)和改變域中的內(nèi)容;用Seek方法,在域中定位;用Truncate方法刪除域中當(dāng)前位置起所有的數(shù)據(jù)。

  20.1.7.1 TBlobStream的屬性和方法

  TBlobStream對(duì)象從TStream直接繼承,沒(méi)有增添新的屬性。它覆蓋了Read、Write 和Seek方法,提供了對(duì)BLOB字段的訪問(wèn)操作;它增添了Truncate方法以實(shí)現(xiàn)BLOB字段中的刪除操作。

  1. Read方法

  聲明:function Read(var Buffer; Count: Longint): Longint;

  Read方法從數(shù)據(jù)庫(kù)域的當(dāng)前位置起復(fù)制Count個(gè)字節(jié)的內(nèi)容到Buffer中。Buffer也必須至少分配Count個(gè)字節(jié)。Read方法返回實(shí)際傳輸?shù)淖止?jié)數(shù),因?yàn)閭鬏數(shù)淖止?jié)數(shù)可能小于Count,所以需要選擇符的邊界判斷。

  2. Write方法

  聲明:function Write(const Buffer; Count: Longint); override; Longint;

  Write方法從Buffer中向數(shù)據(jù)庫(kù)域的當(dāng)前位置復(fù)制Count個(gè)字節(jié)的內(nèi)容。Buffer必須分配有Count個(gè)字節(jié)的內(nèi)存空間,函數(shù)返回實(shí)際傳輸?shù)淖止?jié)數(shù),傳輸過(guò)程也要進(jìn)行選擇符邊界判斷。

  3. Seek方法

  聲明:function Seek(Offset: Longint; Origin: Word): Longint;

  Seek方法重新設(shè)置BLOB流中的指針位置。如果Origin的值是soFromBeginning,則新的指針位置是Offset; 如Origin的值是soFromCurrent,則新的指針位置是Position+Offset;如果Origin的值是SoFromCurrent,則新的指針位置是Size+Offset。函數(shù)返回新的指針位置值。當(dāng)Origin為0(SoFromBegin)時(shí),Offset的值必須大于等于零; 當(dāng)Origin的值為2(SoFromEnd),Offset的值必須小于等于零。

  4. Truncate方法

  聲明:procedure Truncate;

  Truncate方法撤消TBlobField、TBytesField或TVarBytesField中從當(dāng)前位置起的數(shù)據(jù)。

  5. Create方法

  聲明:constructor Create(Field: TBlobField; Mode: TBlobStreamMode);

  Create方法使用Field參數(shù)建立BLOB流與BLOB字段的聯(lián)接。Mode 的值可為bmRead、bmWrite和bmReadWrite。

  20.1.7.2 TBlobStream的實(shí)現(xiàn)原理

  說(shuō)明TBlobStream對(duì)象的實(shí)現(xiàn)原理,不可避免地要涉及它的私有域,下面是私有域的定義:

  TBlobStream = class(TStream)

  private

  FField: TBlobField;

  FDataSet: TDataSet;

  FRecord: PChar;

  FBuffer: PChar;

  FFieldNo: Integer;

  FOpened: Boolean;

  FModified: Boolean;

  FPosition: Longint;

  …

  public

  …

  end;

  FField是與BLOB流相聯(lián)的數(shù)據(jù)庫(kù)BLOB域,該域用于BLOB流的內(nèi)部訪問(wèn)。FDataSet是代表FField所在的數(shù)據(jù)庫(kù),它可以是TTable部件,也可以是TQuery 部件。FRecord和FBuffer都是BLOB流內(nèi)部使用的緩沖區(qū),用于存儲(chǔ)FField所在記錄的數(shù)據(jù),該數(shù)據(jù)記錄中不包含BLOB數(shù)據(jù),TBlobStream使用FRecord作為調(diào)用BDE API函數(shù)的參數(shù)值。FFieldNo代表BLOB字段的字段號(hào),也用于BDE API的參數(shù)傳遞,F(xiàn)Opened和FMocified都是狀態(tài)信息,F(xiàn)Position表示BLOB流的當(dāng)前位置,下面介紹TBlobStream方法實(shí)現(xiàn)。

  1. Create方法和Destroy方法的實(shí)現(xiàn)

  Create方法的功能主要是建立BlobStream流與BLOB字段的聯(lián)系并初始化某些私有變量。其實(shí)現(xiàn)如下:

  constructor TBlobStream.Create(Field: TBlobField; Mode: TBlobStreamMode);

  var

  OpenMode: DbiOpenMode;

  begin

  FField := Field;

  FDataSet := Field.DataSet;

  FRecord := FDataSet.ActiveBuffer;

  FFieldNo := Field.FieldNo;

  if FDataSet.State = dsFilter then

  DBErrorFmt(SNoFieldAccess, [FField.DisplayName]);

  if not FField.FModified then

  begin

  if Mode = bmRead then

  begin

  FBuffer := AllocMem(FDataSet.RecordSize);

  FRecord := FBuffer;

  if not FDataSet.GetCurrentRecord(FBuffer) then Exit;

  OpenMode := dbiReadOnly;

  end else

  begin

  if not (FDataSet.State in [dsEdit, dsInsert]) then DBError(SNotEditing);

  OpenMode := dbiReadWrite;

  end;

  Check(DbiOpenBlob(FDataSet.Handle, FRecord, FFieldNo, OpenMode));

  end;

  FOpened := True;

  if Mode = bmWrite then Truncate;

  end;

  該方法首先是用傳入的Field參數(shù)給FField,F(xiàn)DataSet,F(xiàn)Record和FFieldNo賦值。方法中用AllocMem按當(dāng)前記錄大小分配內(nèi)存,并將指針賦給FBuffer,用DataSet部件的GetCurrentRecord方法,將記錄的值賦給FBuffer,但不包括BLOB數(shù)據(jù)。

  方法中用到的DbiOpenBlob函數(shù)是BDE的API函數(shù),該函數(shù)用于打開(kāi)數(shù)據(jù)庫(kù)中的BLOB字段。

  最后如果方法傳入的Mode參數(shù)值為bmWrite,就調(diào)用Truncate將當(dāng)前位置指針以后的

  數(shù)據(jù)刪除。

  分析這段源程序不難知道:

  ● 讀寫(xiě)B(tài)LOB字段,不允許BLOB字段所在DataSet部件有Filter,否則產(chǎn)生異常事件

  ● 要讀寫(xiě)B(tài)LOB字段,必須將DataSet設(shè)為編輯或插入狀態(tài)

  ● 如果BLOB字段中的數(shù)據(jù)作了修改,則在創(chuàng)建BLOB 流時(shí),不再重新調(diào)用DBiOpenBlob函數(shù),而只是簡(jiǎn)單地將FOpened置為T(mén)rue,這樣可以用多個(gè)BLOB 流對(duì)同一個(gè)BLOB字段讀寫(xiě)

  Destroy方法釋放BLOB字段和為FBuffer分配的緩沖區(qū),其實(shí)現(xiàn)如下:

  destructor TBlobStream.Destroy;

  begin

  if FOpened then

  begin

  if FModified then FField.FModified := True;

  if not FField.FModified then

  DbiFreeBlob(FDataSet.Handle, FRecord, FFieldNo);

  end;

  if FBuffer <> nil then FreeMem(FBuffer, FDataSet.RecordSize);

  if FModified then

  try

  FField.DataChanged;

  except

  Application.HandleException(Self);

  end;

  end;

  如果BLOB流中的數(shù)據(jù)作了修改,就將FField的FModified置為T(mén)rue;如果FField的Modified為False就釋放BLOB字段,如果FBuffer不為空,則釋放臨時(shí)內(nèi)存。最后根據(jù)FModified的值來(lái)決定是否啟動(dòng)FField的事件處理過(guò)程DataChanged。

  不難看出,如果BLOB字段作了修改就不釋放BLOB字段,并且對(duì)BLOB 字段的修改只有到Destroy時(shí)才提交,這是因?yàn)樽x寫(xiě)B(tài)LOB字段時(shí)都避開(kāi)了FField,而直接調(diào)用BDE API函數(shù)。這一點(diǎn)是在應(yīng)用BDE API編程中很重要,即一定要修改相應(yīng)數(shù)據(jù)庫(kù)部件的狀態(tài)。

  2. Read和Write方法的實(shí)現(xiàn)

  Read和Write方法都調(diào)用BDE API函數(shù)完成數(shù)據(jù)庫(kù)BLOB字段的讀寫(xiě),其實(shí)現(xiàn)如下:

  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;

上一頁(yè)  1 2 3 4 5 6 7 8 9 下一頁(yè)
  相關(guān)推薦:2010年9月計(jì)算機(jī)等級(jí)考試試題及答案解析專(zhuān)題
       預(yù)告:名師解析2010年9月計(jì)算機(jī)等級(jí)考試試題答案
       2010年9月計(jì)算機(jī)等級(jí)考試成績(jī)查詢(xún)時(shí)間及入口
       2010年9月計(jì)算機(jī)等考成績(jī)查詢(xún)短信免費(fèi)提醒開(kāi)通
文章搜索
版權(quán)聲明:如果計(jì)算機(jī)等級(jí)考試網(wǎng)所轉(zhuǎn)載內(nèi)容不慎侵犯了您的權(quán)益,請(qǐng)與我們聯(lián)系800@exam8.com,我們將會(huì)及時(shí)處理。如轉(zhuǎn)載本計(jì)算機(jī)等級(jí)考試網(wǎng)內(nèi)容,請(qǐng)注明出處。