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

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

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

  第二十章 開(kāi)發(fā)Delphi對象式數據管理功能

  面向對象技術(shù)是九十年代的主流技術(shù),各類(lèi)應用軟件如果以面向對象的方法構造并且滲透面向對象的風(fēng)格將使軟件具有更高的品質(zhì)。在面向對象程序設計中,對象式數據管理占有很重要的地位。在Delphi中,對對象式數據管理的支持方式是其一大特色。

  Delphi是一個(gè)面向對象的可視化設計與面向對象的語(yǔ)言相結合的集成開(kāi)發(fā)環(huán)境。Delphi的核心是部件。部件是對象的一種。Delphi應用程序完全是由部件來(lái)構造的,因此開(kāi)發(fā)高性能的Delphi應用程序必然會(huì )涉及對象式數據管理技術(shù)。

  對象式數據管理包括兩方面的內容:

  ● 用對象來(lái)管理數據

  ● 對各類(lèi)數據對象(包括對象和部件)的管理

  Delphi在這兩方面都做的相當出色。在Delphi的早期版本Turbo Pascal 中就曾有流(Stream)、群(Collection)和資源(Resource)等專(zhuān)門(mén)用于對象式數據管理的類(lèi)。在Delphi中,這些功能得到了大大的加強。Delphi將對象式數據管理類(lèi)歸結為Stream對象(Stream)和Filer對象(Filer),并將它們應用于可視部件類(lèi)庫(VCL)的方方面面。它們不僅提供了在內存、外存和Windows資源中管理對象的功能,還提供了在數據庫BLOB字段中對象的功能。

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

  20.1 流式對象的實(shí)現原理和應用

  Stream對象,又稱(chēng)流式對象,是TStream、THandleStream、TFileStream、TMemoryStream、TResourceStream和TBlobStream等的統稱(chēng)。它們分別代表了在各種媒介上存儲數據的能力,它們將各種數據類(lèi)型(包括對象和部件) 在內存、外存和數據庫字段中的管理操作抽象為對象方法,并且充分利用了面向對象技術(shù)的優(yōu)點(diǎn),應用程序可以相當容易地在各種Stream對象中拷貝數據。

  下面介紹各種對象的數據和方法及使用方法。

  20.1.1 TStream對象

  TStream對象是能在各種媒介中存儲二進(jìn)制數據的對象的抽象對象。從TStream 對象繼承的對象用于在內存、Windows資源文件、磁盤(pán)文件和數據庫字段等媒介中存儲數據。

  TStream中定義了兩個(gè)屬性:Size和Position。它們分別以字節為單位表示的流的大小和當前指針位置。TStream中定義的方法用于在各種流中讀、寫(xiě)和相互拷貝二進(jìn)制數據。因為所有的Stream對象都是從TStream中繼承來(lái)的,所以在TStream中定義的域和方法都能被Stream對象調用和訪(fǎng)問(wèn)。此外,又由于面向對象技術(shù)的動(dòng)態(tài)聯(lián)編功能,TStream為各種流的應用提供了統一的接口,簡(jiǎn)化了流的使用;不同Stream對象是抽象了對不同存儲媒介的數據上的操作,因此,TStream的需方法為在不同媒介間的數據拷貝提供了最簡(jiǎn)捷的手段。

  20.1.1.1 TStream的屬性和方法

  1. Position屬性

  聲明:property Position: Longint;

  Position屬性指明流中讀寫(xiě)的當前偏移量。

  2. Size屬性

  聲明:property Size: Longint;

  Size屬性指明了以字節為單位的流的的大小,它是只讀的。

  3. CopyFrom方法

  聲明:function CopyFrom(Source: TStream; Count: Longint): Longint;

  CopyFrom從Source所指定的流中拷貝Count個(gè)字節到當前流中, 并將指針從當前位置移動(dòng)Count個(gè)字節數,函數返回值是實(shí)際拷貝的字節數。

  4. Read方法

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

  Read方法從當前流中的當前位置起將Count個(gè)字節的內容復制到Buffer中,并把當前指針向后移動(dòng)Count個(gè)字節數,函數返回值是實(shí)際讀的字節數。如果返回值小于Count,這意味著(zhù)讀操作在讀滿(mǎn)所需字節數前指針已經(jīng)到達了流的尾部。

  Read方法是抽象方法。每個(gè)后繼Stream對象都要根據自己特有的有關(guān)特定存儲媒介的讀操作覆蓋該方法。而且流的所有其它的讀數據的方法(如:ReadBuffer,ReadComponent等)在完成實(shí)際的讀操作時(shí)都調用了Read方法。面向對象的動(dòng)態(tài)聯(lián)編的優(yōu)點(diǎn)就體現在這兒。因為后繼Stream對象只需覆蓋Read方法,而其它讀操作(如ReadBuffer、ReadComponent等)都不需要重新定義,而且TStream還提供了統一的接口。

  5. ReadBuffer方法

  聲明:procedure ReadBuffer(var Buffer; Count: Longint);

  ReadBuffer方法從流中將Count個(gè)字節復制到Buffer 中, 并將流的當前指針向后移動(dòng)Count個(gè)字節。如讀操作超過(guò)流的尾部,ReadBuffer方法引起EReadError異常事件。

  6. ReadComponent方法

  聲明:function ReadComponent(Instance: TComponent): TComponent;

  ReadComponent方法從當前流中讀取由Instance所指定的部件,函數返回所讀的部件。ReadComponent在讀Instance及其擁有的所有對象時(shí)創(chuàng )建了一個(gè)Reader對象并調用它的ReadRootComponent方法。

  如果Instance為nil,ReadComponent的方法基于流中描述的部件類(lèi)型信息創(chuàng )建部件,并返回新創(chuàng )建的部件。

  7. ReadComponentRes方法

  聲明:function ReadComponentRes(Instance: TComponent): TComponent;

  ReadComponentRes方法從流中讀取Instance指定的部件,但是流的當前位置必須是由WriteComponentRes方法所寫(xiě)入的部件的位置。

  ReadComponentRes 首先調用ReadResHeader方法從流中讀取資源頭,然后調用ReadComponent方法讀取Instance。如果流的當前位置不包含一個(gè)資源頭。ReadResHeader將引發(fā)一個(gè)EInvalidImage異常事件。在Classes庫單元中也包含一個(gè)名為ReadComponentRes的函數,該函數執行相同的操作,只不過(guò)它基于應用程序包含的資源建立自己的流。

  8. ReadResHeader方法

  聲明:procedure ReadResHeader;

  ReadResHeader方法從流的當前位置讀取Windows資源文件頭,并將流的當前位置指針移到該文件頭的尾部。如果流不包含一個(gè)有效的資源文件頭,ReadResHeader將引發(fā)一個(gè)EInvalidImage異常事件。

  流的ReadComponentRes方法在從資源文件中讀取部件之前,會(huì )自動(dòng)調用ReadResHeader方法,因此,通常程序員通常不需要自己調用它。

  9. Seek方法

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

  Seek方法將流的當前指針移動(dòng)Offset個(gè)字節,字節移動(dòng)的起點(diǎn)由Origin指定。如果Offset是負數,Seek方法將從所描述的起點(diǎn)往流的頭部移動(dòng)。下表中列出了Origin的不同取值和它們的含義:

  表20.1 函數Seek的參數的取值

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

  常量 值 Seek的起點(diǎn) Offset的取值

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

  SoFromBeginning 0 流的開(kāi)頭 正 數

  SoFromCurrent 1 流的當前位置 正數或負數

  SoFromEnd 2 流的結尾 負 數

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

  10. Write方法

  在Delphi對象式管理的對象中有兩類(lèi)對象的方法都有稱(chēng)為Write的:Stream對象和Filer對象。Stream對象的Write方法將數據寫(xiě)進(jìn)流中。Filer對象通過(guò)相關(guān)的流傳遞數據,在后文中會(huì )介紹這類(lèi)方法。

  Stream對象的Write方法聲明如下:

  function Write(const Buffer; Count: Longint): Longint; virtual; abstract;

  Write方法將Buffer中的Count個(gè)字節寫(xiě)入流中,并將當前位置指針向流的尾部移動(dòng)Count個(gè)字節,函數返回寫(xiě)入的字節數。

  TStream的Write方法是抽象的,每個(gè)繼承的Stream對象都要通過(guò)覆蓋該方法來(lái)提供向特定存儲媒介(內存、磁盤(pán)文件等)寫(xiě)數據的特定方法。流的其它所有寫(xiě)數據的方法(如WriteBuffer、WriteComponent)都調用Write擔當實(shí)際的寫(xiě)操作。

  11. WriteBuffer方法

  聲明:procedure WriteBuffer(const Buffer; Count: Longint);

  WriteBuffer的功能與Write相似。WriteBuffer方法調用Write來(lái)執行實(shí)際的寫(xiě)操作,如果流沒(méi)能寫(xiě)所有字節,WriteBuffer會(huì )觸發(fā)一個(gè)EWriteError異常事件。

  12. WriteComponent方法

  在Stream對象和Filer對象都有被稱(chēng)為WriteComponent的方法。Stream對象的WriteComponent方法將Instance所指定的部件和它所包含的所有部件都寫(xiě)入流中;Writer對象的WriteComponent將指定部件的屬性值寫(xiě)入Writer對象的流中。

  Stream對象的WriteComponent方法聲明是這樣的:

  procedure WriteComponent(Instance: Tcomponent);

  WriteComponent創(chuàng )建一個(gè)Writer對象,并調用Writer的WriteRootComponent方法將Instance及其擁有的對象寫(xiě)入流。

  13. WriteComponentRes方法

  聲明:WriteComponentRes(const ResName: String; Instance: TComponent);

  WriteComponentRes方法首先往流中寫(xiě)入標準Windows 資源文件頭,然后將Instance指定的部件寫(xiě)入流中。要讀由WriteComponentRes寫(xiě)入的部件,必須調用ReadComponentRes方法。

  WriteComponentRes使用ResName傳入的字符串作為資源文件頭的資源名,然后調用WriteComponent方法將Instance和它擁有的部件寫(xiě)入流。

  14. WriteDescendant方法

  聲明:procedure WriteDescendant(Instance Ancestor: TComponent);

  Stream對象的WriteDescendant方法創(chuàng )建一個(gè)Writer對象,然后調入該對象的WriteDescendant方法將Instance部件寫(xiě)入流中。Instance可以是從Ancestor部件繼承的窗體,也可以是在從祖先窗體中繼承的窗體中相應于祖先窗體中Ancestor部件的部件。

  15. WriteDescendantRes方法

  聲明:procedure WriteDescendantRes(const ResName: String;

  Instance, Ancestor: TComponent);

  WriteDescendantRes方法將Windows資源文件頭寫(xiě)入流,并使用ResName作用資源名,然后調用WriteDescendant方法,將Instance寫(xiě)入流。

  20.1.1.2 TStream的實(shí)現原理

  TStream對象是Stream對象的基礎類(lèi),這是Stream對象的基礎。為了能在不同媒介上的存儲數據對象,后繼的Stream對象主要是在Read和Write方法上做了改進(jìn),。因此,了解TStream是掌握Stream對象管理的核心。Borland公司雖然提供了Stream對象的接口說(shuō)明文檔,但對于其實(shí)現和應用方法卻沒(méi)有提及,筆者是從Borland Delphi 2.0 Client/Server Suite 提供的源代碼和部分例子程序中掌握了流式對象技術(shù)。

  下面就從TStream的屬性和方法的實(shí)現開(kāi)始。

  1. TStream屬性的實(shí)現

  前面介紹過(guò),TStream具有Position和Size兩個(gè)屬性,作為抽象數據類(lèi)型,它抽象了在各種存儲媒介中讀寫(xiě)數據所需要經(jīng)常訪(fǎng)問(wèn)的域。那么它們是怎樣實(shí)現的呢?

  在自定義部件編寫(xiě)這一章中介紹過(guò)部件屬性定義中的讀寫(xiě)控制。Position和Size也作了讀寫(xiě)控制。定義如下:

  property Position: Longint read GetPosition write SetPosition;

  property Size: Longint read GetSize;

  由上可知,Position是可讀寫(xiě)屬性,而Size是只讀的。

  Position屬性的實(shí)現就體現在GetPosition和SetPosition。當在程序運行過(guò)程中,任何讀取Position的值和給Position賦值的操作都會(huì )自動(dòng)觸發(fā)私有方法GetPosition和SetPosition。兩個(gè)方法的聲明如下:

  function TStream.GetPosition: Longint;

  begin

  Result := Seek(0, 1);

  end;

  procedure TStream.SetPosition(Pos: Longint);

  begin

  Seek(Pos, 0);

  end;

  在設置位置時(shí),Delphi編譯機制會(huì )自動(dòng)將Position傳為Pos。

  前面介紹過(guò)Seek的使用方法,第一參數是移動(dòng)偏移量,第二個(gè)參數是移動(dòng)的起點(diǎn),返回值是移動(dòng)后的指針位置。

  Size屬性的實(shí)現只有讀控制,完全屏蔽了寫(xiě)操作。讀控制方法GetSize實(shí)現如下:

  function TStream.GetSize: Longint;

  var

  Pos: Longint;

  begin

  Pos := Seek(0, 1);

  Result := Seek(0, 2);

  Seek(Pos, 0);

  end;

  2. TStream方法的實(shí)現

 、 CopyFrom方法

  CopyFrom是Stream對象中很有用的方法,它用于在不同存儲媒介中拷貝數據。例如,內存與外部文件之間、內存與數據庫字段之間等。它簡(jiǎn)化了許多內存分配、文件打開(kāi)和讀寫(xiě)等的細節,將所有拷貝操作都統一到Stream對象上。

  前面曾介紹:CopyFrom方法帶Source和Count兩個(gè)參數并返回長(cháng)整型。該方法將Count個(gè)字節的內容從Source拷貝到當前流中,如果Count值為0則拷貝所有數據。

  function TStream.CopyFrom(Source: TStream; Count: Longint): Longint;

  const

  MaxBufSize = $F000;

  var

  BufSize, N: Integer;

  Buffer: PChar;

  begin

  if Count = 0 then

  begin

  Source.Position := 0;

  CouNG="ZH-CN">資源文件中的部件時(shí)調用,通常程序員不需自己調用。如果讀取的不是資源文件ReadResHeader,將觸發(fā)異常事件。

  procedure TStream.ReadResHeader;

  var

  ReadCount: Longint;

  Header: array[0..79] of Char;

  begin

  FillChar(Header, SizeOf(Header), 0);

  ReadCount := Read(Header, SizeOf(Header) - 1);

  if (Byte((@Header[0])^) = $FF) and (Word((@Header[1])^) = 10) then

  Seek(StrLen(Header + 3) + 10 - ReadCount, 1)

  else

  raise EInvalidImage.CreateRes(SInvalidImage);

  end;

  ReadComponentRes在Windows資源文件中讀取部件,為了判斷是否是資源文件,它首先調用ReadResHeader方法,然后調用ReadComponent方法讀取Instance指定的部件。下面是它的實(shí)現:

  function TStream.ReadComponentRes(Instance: TComponent): TComponent;

  begin

  ReadResHeader;

  Result := ReadComponent(Instance);

  end;

  與ReadComponentRes相應的寫(xiě)方法是WriteComponentRes,Delphi 調用這兩個(gè)方法讀寫(xiě)窗體文件(DFM文件),在后面書(shū)中會(huì )舉用這兩個(gè)方法讀取DFM文件的例子。

 、 WriteComponent和WriteDescendant方法

  Stream對象的WriteDescendant方法在實(shí)現過(guò)程中,創(chuàng )建了TWriter對象,然后利用TWriter的WriteDescendant方法將Instance寫(xiě)入流。而WriteComponent方法只是簡(jiǎn)單地調用WriteDescendant方法將Instance寫(xiě)入流。它們的實(shí)現如下:

  procedure TStream.WriteComponent(Instance: TComponent);

  begin

  WriteDescendent(Instance, nil);

  end;

  procedure TStream.WriteDescendent(Instance, Ancestor: TComponent);

  var

  Writer: TWriter;

  begin

  Writer := TWriter.Create(Self, 4096);

  try

  Writer.WriteDescendent(Instance, Ancestor);

  finally

  Writer.Free;

  end;

  end;

 、 WriteDescendantRes和WriteComponentRes方法

  WriteDescendantRes方法用于將部件寫(xiě)入Windows資源文件;而WriteComponentRes 方法只是簡(jiǎn)單地調用WriteDescendantRes方法,它們的實(shí)現如下:

  procedure TStream.WriteComponentRes(const ResName: string; Instance:

  TComponent);

  begin

  WriteDescendentRes(ResName, Instance, nil);

  end;

  procedure TStream.WriteDescendentRes(const ResName: string; Instance,

  Ancestor: TComponent);

  var

  HeaderSize: Integer;

  Origin, ImageSize: Longint;

  Header: array[0..79] of Char;

  begin

  Byte((@Header[0])^) := $FF;

  Word((@Header[1])^) := 10;

  HeaderSize := StrLen(StrUpper(StrPLCopy(@Header[3], ResName, 63))) + 10;

  Word((@Header[HeaderSize - 6])^) := $1030;

  Longint((@Header[HeaderSize - 4])^) := 0;

  WriteBuffer(Header, HeaderSize);

  Origin := Position;

  WriteDescendent(Instance, Ancestor);

  ImageSize := Position - Origin;

  Position := Origin - 4;

  WriteBuffer(ImageSize, SizeOf(Longint));

  Position := Origin + ImageSize;

  end;

  WriteCompnentRes是與ReadComponentRes相應的對象寫(xiě)方法,這兩個(gè)方法相互配合可讀取Delphi的DFM文件,從而利用Delphi系統的功能。

  20.1.2 THandleStream對象

  THandleStream對象的行為特別象FileStream對象,所不同的是它通過(guò)已創(chuàng )建的文件句柄而不是文件名來(lái)存儲流中的數據。

  THandleStream對象定義了Handle屬性,該屬性提供了對文件句柄的只讀訪(fǎng)問(wèn),并且Handle屬性可以作為Delphi的RTL文件管理函數的參數,利用文件類(lèi)函數來(lái)讀寫(xiě)數據。THandleStream覆蓋了構造函數Create,該函數帶有Handle 參數,該參數指定與THandleStream對象相關(guān)的文件句柄。

  20.1.2.1 THandleStream的屬性的方法:

  1. Handle屬性

  聲明:property Handle: Integer;

  Handle屬性提供了對文件句柄的只讀訪(fǎng)問(wèn),該句柄由THandleStream的構造方法Create傳入。因此除了用THandleStream提供的方法外,也可以用文件管理函數對句柄進(jìn)行操作。實(shí)際上,THandleStream的方法在實(shí)現上也是運用文件管理函數進(jìn)行實(shí)際的讀寫(xiě)操作。

  2. Create方法

  聲明:constructor Create(AHandle: Integer);

  Create方法使用傳入的Handle參數創(chuàng )建一個(gè)與特定文件句柄相聯(lián)的THandleStream對象,并且將AHandle賦給流的Handle屬性。

  3. Read、Write和Seek方法

  這三個(gè)方法是TStream的虛方法,只是在THandleStream 中覆蓋了這三個(gè)方法,以實(shí)現特定媒介──文件的數據存取。后面會(huì )詳細介紹這三個(gè)方法的實(shí)現。

  20.1.2.2 THandleStream的實(shí)現原理

  THandleStream是從TStream繼承來(lái)的,因此可以共用TStream中的屬性和大多數方法。THandleStream在實(shí)現上主要是增加了一個(gè)屬性Handle和覆蓋了Create、Read、Write和Seek四個(gè)方法。

  1. 屬性的實(shí)現

  Handle屬性的實(shí)現正如Delphi大多數屬性的實(shí)現那樣,先在對象定義的private部分聲明一個(gè)存放數據的變量FHandle,然后在定義的public部分聲明屬性Handle,其中屬性定義的讀寫(xiě)控制部分加上只讀控制,讀控制只是直接讀取FHandle變量的值,其實(shí)現如下:

  THandleStream = class(TStream)

  private

  FHandle: Integer;

  public

  …

  property Handle: Integer read FHandle;

  end;

  2. 方法的實(shí)現

  THandleStream的Create方法,以AHandle作為參數,在方法里面只是簡(jiǎn)單的將AHandle的值賦給FHandle,其實(shí)現如下:

  constructor THandleStream.Create(AHandle: Integer);

  begin

  FHandle := AHandle;

  end;

  為實(shí)現針對文件的數據對象存儲,THandleStream的Read、Write和Seek方法覆蓋了TStream中的相應方法。它們的實(shí)現都調用了Windows的文件管理函數。

  Read方法調用FileRead函數實(shí)現文件讀操作,其實(shí)現如下:

  function THandleStream.Read(var Buffer; Count: Longint): Longint;

  begin

  Result := FileRead(FHandle, Buffer, Count);

  if Result = -1 then Result := 0;

  end;

  Write方法調用FileWrite函數實(shí)現文件寫(xiě)操作,其實(shí)現如下:

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

  begin

  Result := FileWrite(FHandle, Buffer, Count);

  if Result = -1 then Result := 0;

  end;

  Seek方法調用FileSeek函數實(shí)現文件指針的移動(dòng),其實(shí)現如下:

  function THandleStream.Seek(Offset: Longint; Origin: Word): Longint;

  begin

  Result := FileSeek(FHandle, Offset, Origin);

  end;

  20.1.3 TFileStream對象

  TFileStream對象是在磁盤(pán)文件上存儲數據的Stream對象。TFileStream是從THandleStream繼承下來(lái)的,它和THandleStream一樣都是實(shí)現文件的存取操作。不同之處在于THandleStream用句柄訪(fǎng)問(wèn)文件,而TFileStream用文件名訪(fǎng)問(wèn)文件。實(shí)際上TFileStream是THandleStream上的一層包裝,其內核是THandleStream的屬性和方法。

  TFileStream中沒(méi)有增加新的屬性和方法。它只是覆蓋了的構造方法Create和析構方法Destory。在Create方法中帶兩個(gè)參數FileName和Mode。FileName描述要創(chuàng )建或打開(kāi)的文件名,而Mode描述文件模式如fmCreate、fmOpenRead和fmOpenWrite等。Create方法首先使用FileCreate或FileOpen函數創(chuàng )建或打開(kāi)名為FileName的文件,再將得到的文件句柄賦給FHandle。TFileStream的文件讀寫(xiě)操作都是由從THandleStream繼承的Read

  var

  Stream: TStream;

  begin

  Stream := TFileStream.Create(FileName, fmCreate);

  try

  SaveToStream(Stream);

  finally

  Stream.Free;

  end;

  end;

  在Delphi 的許多對象的SaveToStream 和SaveToFile、LoadFromStream和LoadFromFile方法的實(shí)現都有類(lèi)似的嵌套結構。

  20.1.5 TMemoryStream對象

  TMemoryStream對象是一個(gè)管理動(dòng)態(tài)內存中的數據的Stream對象,它是從TCustomMemoryStream中繼承下來(lái)的,除了從TCustomMemoryStream中繼承的屬性和方法外,它還增加和覆蓋了一些用于從磁盤(pán)文件和其它注臺讀數據的方法。它還提供了寫(xiě)入、消除內存內容的動(dòng)態(tài)內存管理方法。下面介紹它的這些屬性和方法。

  20.1.5.1 TMemoryStream的屬性和方法

  1. Capacity屬性

  聲明:property Copacity: Longint;

  Capacity屬性決定了分配給內存流的內存池的大小。這與Size屬性有些不同。Size屬性是描述流中數據的大小。在程序中可以將Capacity 的值設置的比數據所需最大內存大一些,這樣可以避免頻繁地重新分配。

  2. Realloc方法

  聲明:function Realloc(var NewCapacity: Longint): Pointer; virtual;

  Realloc方法,以8K為單位分配動(dòng)態(tài)內存,內存的大小由NewCapacity指定,函數返回指向所分配內存的指針。

  3. SetSize方法

  SetSize方法消除內存流中包含的數據,并將內存流中內存池的大小設為Size字節。如果Size為零,是SetSize方法將釋放已有的內存池,并將Memory屬性置為nil;否則,SetSize方法將內存池大小調整為Size。

  4. Clear方法

  聲明:procedure Clear;

  Clear方法釋放內存中的內存池,并將Memory屬性置為nil。在調用Clear方法后,Size和Position屬性都為0。

  5. LoadFromStream方法

  聲明:procedure LoadFromStream(Stream: TStream);

  LoadFromStream方法將Stream指定的流中的全部?jì)热輳椭频組emoryStream中,復制過(guò)程將取代已有內容,使MemoryStream成為Stream的一份拷貝。

  6. LoadFromFile方法

  聲明:procedure LoadFromFile(count FileName: String);

  LoadFromFile方法將FileName指定文件的所有內容復制到MemoryStream中,并取代已有內容。調用LoadFromFile方法后,MemoryStream將成為文件內容在內存中的完整拷貝。

  20.1.5.2 TMemoryStream對象的實(shí)現原理

  TMemoryStream從TCustomMemoryStream對象直接繼承,因此可以享用TCustomMemoryStream的屬性和方法。前面講過(guò),TCustomMemoryStream是用于內存中數據操作的抽象對象,它為MemoryStream對象的實(shí)現提供了框架,框架中的內容還要由具體MemoryStream對象去填充。TMemoryStream對象就是按動(dòng)態(tài)內存管理的需要填充框架中的具體內容。下面介紹TMemoryStream對象的實(shí)現。

  1. TMemoryStream屬性的實(shí)現

  TMemoryStream在其protected部分增加了一個(gè)Capacity屬性,該屬性決定了MemoryStream所占動(dòng)態(tài)內存的大小。TMemoryStream首先在private部分聲明了FCapacity變量作為存儲Capacity屬性值的數據域,然后在protected部分聲明了該屬性。在屬性聲明的讀控制部分簡(jiǎn)單讀取FCapacity的值,在寫(xiě)控制處調用了方法SetCapacity。該方法除了給FCapacity賦值外還執行了修改Capacity屬性所必需操作如狀態(tài)改變等。

  下面是屬性的實(shí)現:

  TMemoryStream = class(TCustomMemoryStream)

  private

  FCapacity: Longint;

  procedure SetCapacity(NewCapacity: Longint);

  protected

  …

  property Capacity: Longint read FCapacity write SetCapacity;

  public

  …

  end;

  寫(xiě)控制方法SetCapacity的實(shí)現是這樣的:

  procedure TMemoryStream.SetCapacity(NewCapacity: Longint);

  begin

  SetPointer(Realloc(NewCapacity), FSize);

  FCapacity := NewCapacity;

  end;

  在SetCapacity 方法先是調用Realloc重新分配內存,然后用NewCapacity的值給FCapacity賦值。Realloc方法進(jìn)行某些對象狀態(tài)的改變。

1 2 3 4 5 6 7 8 9 下一頁(yè)
  相關(guān)推薦:2010年9月計算機等級考試試題及答案解析專(zhuān)題
       預告:名師解析2010年9月計算機等級考試試題答案
       2010年9月計算機等級考試成績(jì)查詢(xún)時(shí)間及入口
       2010年9月計算機等考成績(jì)查詢(xún)短信免費提醒開(kāi)通
文章搜索
版權聲明:如果計算機等級考試網(wǎng)所轉載內容不慎侵犯了您的權益,請與我們聯(lián)系800@exam8.com,我們將會(huì )及時(shí)處理。如轉載本計算機等級考試網(wǎng)內容,請注明出處。
午夜夜伦鲁鲁片免费无码_亚洲国产男人本色在线观看的a站_国产极品粉嫩馒头一线天免费_亚洲А∨天堂2021无码