20.2.1.1 TFiler對象的屬性和方法
1. Root屬性
聲明:property Root: TComponent;
Root 屬性給Filer對象指出被讀寫的對象中哪一個對象是根或主要擁有者。RootComponent和WriteRootComponent方法在讀和寫部件及其擁有的部件前先設置Root的值。
2. Ancestor屬性
聲明:property Ancestor: TPersistent;
Ancestor屬性用于往繼承下來的窗體中寫部件,因為當寫部件時,Write對象只需要寫入與所繼承的部件不同的屬性,所以在寫之前要跟蹤每個繼承的部件,并且比較它們的屬性。
如果Ancestor為nil,就表示沒有相應的繼承的部件,Writer對象應當將部件完全寫入流。Ancestor一般為nil,只有當調用WriteDescendant和WriteDescendantRes時,才給賦值。當編寫和覆蓋DefineProperties時,必須設置Ancestor的值。
3. IgnoreChildren屬性
聲明:property Ignorechildren: Boolean;
IgnoreChildren屬性使一個Writer對象存儲部件時可以不存儲該部件擁有的部件。如果IgnoreChildren屬性為True,則Writer對象存儲部件不存它擁有的子部件。否則,Writer對象將所有其擁有的對象寫入流。
4. Create方法
聲明:constructor Create(Stream: TStream; BufSize: Cardinal);
Create方法創建一個新的Filer對象,建立它和流Stream的聯系;并且給它分配一個緩沖區Buffer。Buffer的大小由BufSize指定。
5. Defineproperty方法
聲明:procedure Defineproperty(const Name: String; ReadData: TReaderProc;
WriteData: TWriterProc; HasData: Boolean); virtual; abstract;
Defineproperty方法定義Filer對象將作為屬性存儲的數據。Name參數描述接受的屬性名,該屬性不在published部分定義。ReadData和WriteData參數指定在存取對象時讀和寫所需數據的方法。HasData參數在運行時決定了屬性是否有數據要存儲。
只有當對象有數據要存儲時,才在該對象的DefineProperties中調用DefineProperty。DefineProperties有一個Filer對象作為它的參數,調用的就是該Filer對象的DefineProperty和DefineBinaryProperty方法。當定義屬性時,Writer對象應當引用Ancestor屬性,如果該屬性非空,Writer對象應當只寫入與從Ancestor繼承的不同的屬性的值。
一個最簡單的例子是TComponent的DefineProperties方法。盡管TComponent 沒有在published中定義Left、Top屬性,但該方法存儲了部件的位置信息。
procedure TComponent.DefineProperties(Filer: TFiler);
begin
Filer.DefineProperty('Left', ReadLeft, WriteLeft, LongRec(FDesignInfo).Lo <> 0);
Filer.DefineProperty('Top', ReadTop, WriteTop, LongRec(FDesignInfo).Hi <> 0);
end;
6. DefineBinaryproperty方法
聲明:procedure DefineBinaryproperty(const Name: String;
ReadData, WriteData: TStreamProc;
HisData: Boolean); virtual; abstract;
DefineBinaryProperty方法定義Filer對象作為屬性存儲的二進制數據。Name參數描述屬性名。ReadData和WriteData參數描述所存儲的對象中讀寫所需數據的方法。HasData參數在運行時決定屬性是否有數據要存。
DefineBinaryProperty和DefineProperty方法的不同之處在于,二進制型的屬性直接用Stream對象讀寫,而不是通過Filer對象。通過ReadData和WriteData傳入的方法,直接將對象數據寫入流或從流讀出。
DefineBinaryProperty屬性用得較少。只有標準的VCL對象定義了象圖形、圖像之類的二進制屬性的部件中才用它。
7. FlushBuffer方法
聲明:procedure FlushBuffer; virtual: abstract;
FlushBuffer方法用于使Filer對象的緩沖區與相聯的Stream對象同步。對Reader對象來說,是通過重新分配緩沖區;對于Writer對象是通過寫入當前緩沖區。
FlushBuffer是一個抽象方法,TReader和TWriter都覆蓋了它,提供了具體實現。
20.2.1.2 TFiler對象的實現原理
TFiler對象是Filer對象的基礎類,它定義的大多數方法都是抽象類型的,沒有具體實現它,這些方法要在TReader和TWrite中覆蓋。但它們提供了Filer對象的框架,了解它無疑是很重要的。
1. TFiler對象屬性的實現
TFiler對象定義了三個屬性:Root、Ancestor和IgnoreChildren。正如定義對象屬性通常所采用的方法那樣,要在private部分定義存儲屬性值的數據域,然后在public或Published部分定義該屬性,并按需要增加讀寫控制。它們的定義如下:
TFiler = class(TObject)
private
…
FRoot: TComponent;
FAncestor: TPersistent;
FIgnoreChildren: Boolean;
public
…
property Root: TComponent read FRoot write FRoot;
property Ancestor: TPersistent read FAncestor write FAncestor;
property IgnoreChildren: Boolean read FIgnoreChildren write FIgnoreChildren;
end;
它們在讀寫控制上都是直接讀寫私有的數據域。
在介紹TReader和TWriter的實現,我們還會看到這幾個屬性的原理介紹。
2. TFiler對象方法的實現
在TFiler對象定義的眾多方法中很多都是抽象類方法,沒有具體實現。在TFiler 的后繼對象TReader中覆蓋了這些方法。在后面章節,會介紹這些方法的實現。
在TFiler對象中有具體實現的有兩個方法Create和Destroy。
⑴ Create方法的實現
Create方法是TFiler的構造方法,它有兩個參數Stream和BufSize。Stream是指定與TFiler對象相聯系的Stream對象,Filer對象都是用Stream對象完成具體的讀寫。BufSize是TFiler對象內部開設的緩沖區的大小。Filer對象內部開設緩沖區是為了加快數據的讀寫,它的實現如下:
constructor TFiler.Create(Stream: TStream; BufSize: Integer);
begin
FStream := Stream;
GetMem(FBuffer, BufSize);
FBufSize := BufSize;
end;
FStream、FBuffer和FBufSize都是TFiler在private部分定義的數據域。FStream表示與Filer對象相聯的Stream對象,FBuffer指向Filer對象內部開設的緩沖區,FBufSize是內部緩沖區的大小。Create方法用Stream參數值給FStream賦值,然后用GetMem分配BufSize大小的動態內存作為內部緩沖區。
⑵ Destroy方法的實現
Destroy方法是TFiler對象的析構函數,它的作用就是釋放動態內存。
destructor TFiler.Destroy;
begin
if FBuffer <> nil then FreeMem(FBuffer, FBufSize);
end;
20.2.2 TWriter對象
TWriter 對象是可實例化的,往流中寫數據的Filer對象。TWriter對象直接從TFiler繼承而來,除了覆蓋從TFiler繼承的方法外,還增加了大量的關于寫各種數據類型(如Integer、String和Component等)的方法。TWriter對象和TReader 對象配合使用將使對象讀寫發揮巨大作用。
20.2.2.1 TWriter對象的屬性和方法
1. Position屬性
聲明:property Position: Longint;
TWriter對象的Position屬性表示相關聯的流中的當前要寫的位置,TReader 對象也有這個屬性,但與TReader對象不同的是TWriter對象的Position的值比流的Position值小,這一點一看屬性實現就清楚了。
2. RootAncesstor屬性
聲明:property RootAncestor: TComponent;
RootAncestor屬性表示的是Root屬性所指的部件的祖先。如果Root 是繼承的窗體,Writer對象將窗體擁有部件與祖先窗體中的相應部件依次比較,然后只寫入那些與祖先中的不同的部件。
3. Write方法
聲明:procedure Write(const Buf; Count: Longint);
Write方法從Buf中往與Writer相關聯的流中寫入Count個字節。
4. WriteListBegin方法
聲明:procedure WriteListBegin;
WriteListBegin方法往Write對象的流中寫入項目列表開始標志,該標志意味著后面存儲有一連串的項目。Reader對象,在讀這一連串項目時先調用ReadListBegin方法讀取該標志位,然后用EndOfList判斷是否列表結束,并用循環語句讀取項目。在調用WriteListBegin方法的后面必須調用WriteListEnd方法寫列表結束標志,相應的在Reader對象中有ReadListEnd方法讀取該結束標志。
5. WriteListEnd方法
聲明:procedure WriteListEnd;
WriteListEnd方法在流中,寫入項目列表結束標志,它是與WriteListBegin相匹配的方法。
6. WriteBoolean方法
聲明:procedure WriteBoolean(Value: Boolean);
WriteBoolean方法將Value傳入的布爾值寫入流中。 [1] [2] 下一頁
|