首頁 考試吧論壇 Exam8視線 考試商城 網絡課程 模擬考試 考友錄 實用文檔 求職招聘 論文下載 | ||
![]() |
2011中考 | 2011高考 | 2012考研 | 考研培訓 | 在職研 | 自學考試 | 成人高考 | 法律碩士 | MBA考試 MPA考試 | 中科院 |
|
![]() |
四六級 | 職稱英語 | 商務英語 | 公共英語 | 托福 | 雅思 | 專四專八 | 口譯筆譯 | 博思 | GRE GMAT 新概念英語 | 成人英語三級 | 申碩英語 | 攻碩英語 | 職稱日語 | 日語學習 | 法語 | 德語 | 韓語 |
|
![]() |
計算機等級考試 | 軟件水平考試 | 職稱計算機 | 微軟認證 | 思科認證 | Oracle認證 | Linux認證 華為認證 | Java認證 |
|
![]() |
公務員 | 報關員 | 銀行從業資格 | 證券從業資格 | 期貨從業資格 | 司法考試 | 法律顧問 | 導游資格 報檢員 | 教師資格 | 社會工作者 | 外銷員 | 國際商務師 | 跟單員 | 單證員 | 物流師 | 價格鑒證師 人力資源 | 管理咨詢師考試 | 秘書資格 | 心理咨詢師考試 | 出版專業資格 | 廣告師職業水平 駕駛員 | 網絡編輯 |
|
![]() |
衛生資格 | 執業醫師 | 執業藥師 | 執業護士 | |
![]() |
會計從業資格考試(會計證) | 經濟師 | 會計職稱 | 注冊會計師 | 審計師 | 注冊稅務師 注冊資產評估師 | 高級會計師 | ACCA | 統計師 | 精算師 | 理財規劃師 | 國際內審師 |
|
![]() |
一級建造師 | 二級建造師 | 造價工程師 | 造價員 | 咨詢工程師 | 監理工程師 | 安全工程師 質量工程師 | 物業管理師 | 招標師 | 結構工程師 | 建筑師 | 房地產估價師 | 土地估價師 | 巖土師 設備監理師 | 房地產經紀人 | 投資項目管理師 | 土地登記代理人 | 環境影響評價師 | 環保工程師 城市規劃師 | 公路監理師 | 公路造價師 | 安全評價師 | 電氣工程師 | 注冊測繪師 | 注冊計量師 |
|
![]() |
繽紛校園 | 實用文檔 | 英語學習 | 作文大全 | 求職招聘 | 論文下載 | 訪談 | 游戲 |
12. WriteSignature方法
聲明:procedure WriteSignature;
WriteSignature方法將Delphi Filer對象標簽寫入流中。WriteRootComponent方法在將部件寫入流之前先調用WriteSignature方法寫入Filer標簽。Reader對象在讀部件之前調用ReadSignature方法讀取該標簽以指導讀操作。
13. WritComponent方法
聲明:procedure WriteComponent(Component: TComponent);
WriteComponent方法調用參數Component的WriteState方法將部件寫入流中。在調用WriteState之前,WriteComponent還將Component的ComponetnState屬性置為csWriting。當WriteState返回時再清除csWriting.
14. WriteRootComponent方法
聲明:procedure WriteRootComponent(Root: TComponent);
WriteRootComponent方法將Writer對象Root屬性設為參數Root帶的值,然后調用WriteSignature方法往流中寫入Filer對象標簽,最后調用WriteComponent方法在流中存儲Root部件。
20.2.2.2 TWriter對象的實現
TWriter對象提供了許多往流中寫各種類型數據的方法,這對于程序員來說是很重要的功能。TWrite對象往流中寫數據是依據不同的數據采取不同的格式的。 因此要掌握TWriter對象的實現和應用方法,必須了解Writer對象存儲數據的格式。
首先要說明的是,每個Filer對象的流中都包含有Filer對象標簽。該標簽占四個字節其值為“TPF0”。Filer對象為WriteSignature和ReadSignature方法存取該標簽。該標簽主要用于Reader對象讀數據(部件等)時,指導讀操作。
其次,Writer對象在存儲數據前都要留一個字節的標志位,以指出后面存放的是什么類型的數據。該字節為TValueType類型的值。TValueType是枚舉類型,占一個字節空間,其定義如下:
TValueType = (VaNull, VaList, VaInt8, VaInt16, VaInt32, VaEntended, VaString, VaIdent,
VaFalse, VaTrue, VaBinary, VaSet, VaLString, VaNil, VaCollection);
因此,對Writer對象的每一個寫數據方法,在實現上,都要先寫標志位再寫相應的數據;而Reader對象的每一個讀數據方法都要先讀標志位進行判斷,如果符合就讀數據,否則產生一個讀數據無效的異常事件。VaList標志有著特殊的用途,它是用來標識后面將有一連串類型相同的項目,而標識連續項目結束的標志是VaNull。因此,在Writer對象寫連續若干個相同項目時,先用WriteListBegin寫入VaList標志,寫完數據項目后,再寫出VaNull標志;而讀這些數據時,以ReadListBegin開始,ReadListEnd結束,中間用EndofList函數判斷是否有VaNull標志。
下面就介紹它們的實現。
1. TWriter對象屬性的實現
TWriter對象直接從TFiler對象繼承,它只增加了Position和RootAncestor屬性。
RootAncestor屬性在private部分有數據域FRootAncestor存入其值。在屬性定義的讀與控制上都是直接讀取該值。
Position屬性的定義中包含了兩個讀寫控制方法:GetPosition和SetPosition:
TWriter = class(TFiler)
private
FRootAncestor: TComponent;
…
function GetPosition: Longint;
procedure SetPosition(Value: Longint);
public
…
property Position: Longint read GetPosition write SetPosition;
property RootAncestor: TComponent read FRootAncestor write FRootAncestor;
end;
GetPosition和SetPosition方法實現如下:
function TWriter.GetPosition: Longint;
begin
Result := FStream.Position + FBufPos;
end;
procedure TWriter.SetPosition(Value: Longint);
var
StreamPosition: Longint;
begin
StreamPosition := FStream.Position;
{ 只清除越界的緩沖區 }
if (Value < StreamPosition) or (Value > StreamPosition + FBufPos) then
begin
WriteBuffer;
FStream.Position := Value;
end
else FBufPos := Value - StreamPosition;
end;
WriteBuffer是TWriter對象定義的私有方法,它的作用是將Writer 對象內部緩沖區中的有效數據寫入流中,并將FBufPos置為0。Writer對象的FlushBuffer對象就是用WriteBuffer方法刷新緩沖區。
在SetPosition方法中,如果Value值超出了邊界(FStream.Position,FStream.Position + FBufPos),就將緩沖區中的內容寫入流,重新設置緩沖區在流中的相對位置;否則,就只是移動FBufPos指針。
2. TWriter方法的實現
⑴ WriteListBegin和WriteListEnd的實現
這兩個方法都是用于寫連續若干個相同類型的值。WriteListBegin寫入VaList標志,WriteListEnd寫入VaNull標志。
procedure TWriter.WriteListBegin;
begin
WriteValue(vaList);
end;
procedure TWriter.WriteListEnd;
begin
WriteValue(vaNull);
end;
這兩個方法都調用TWriter對象的WriteValue方法,該方法主要用于寫入TValueType類型的值。
procedure TWriter.WriteValue(Value: TValueType);
begin
Write(Value, SizeOf(Value));
end;
、 簡單數據類型的寫入
簡單數據類型指的是整型、字符型、字符串型、浮點型、布爾型等。TWriter對象都定義了相應的寫入方法。
WriteInteger方法用于寫入整型數據。
procedure TWriter.WriteInteger(Value: Longint);
begin
if (Value >= -128) and (Value <= 127) then
begin
WriteValue(vaInt8);
Write(Value, SizeOf(Shortint));
end else
if (Value >= -32768) and (Value <= 32767) then
begin
WriteValue(vaInt16);
Write(Value, SizeOf(Smallint));
end else
begin
WriteValue(vaInt32);
Write(Value, SizeOf(Longint));
end;
end;
WriteInteger方法將整型數據分為8位、16位和32位三種,并分別用vaInt8、vaInt16和VaInt32。
WriteBoolean用于寫入布爾型數據:
procedure TWriter.WriteBoolean(Value: Boolean);
begin
if Value then
WriteValue(vaTrue) else
WriteValue(vaFalse);
end;
與其它數據類型不同的是布爾型數據只使用了標志位是存儲布爾值,在標志位后沒有數據。
WriteFloat方法用于寫入浮點型數據。
procedure TWriter.WriteFloat(Value: Extended);
begin
WriteValue(vaExtended);
Write(Value, SizeOf(Extended));
end;
字符串“True”、“False”和“nil”作為標識符傳入是由于Delphi的特殊需要。如果是“True”、“False”和“nil”則寫入VaTrue、VaFalse和VaNil,否則寫入VaIdent標志,接著以字符串形式寫入標識符。
WriteString方法用于寫入字符串
procedure TWriter.WriteString(const Value: string);
var
L: Integer;
begin
L := Length(Value);
if L <= 255 then
begin
WriteValue(vaString);
Write(L, SizeOf(Byte));
end else
begin
WriteValue(vaLString);
Write(L, SizeOf(Integer));
end;
Write(Pointer(Value)^, L);
end;
Delphi的字符串類型有兩種。一種長度小于256個字節,另一種長度小于65536 個字節。WriteString方法區分這兩類情況存儲字符串,一種設置VaStirng標志,另一種設置VaLString。然后存儲字符串的長度值,最后存儲字符串數據。
WriteChar方法用于寫入字符。
procedure TWriter.WriteChar(Value: Char);
begin
WriteString(Value);
end;
字符類型的讀寫是用讀寫字符串的方法,在讀的時候,判斷字節數為1時,則為字符型。
、 部件的寫入
TWriter對象中與寫入部件有關的方法有WriteSignature、WritePrefix、WriteComponent、WriteDescendant和WriteRootComponent。
WriteSignature方法用于往流中寫入Filer對象標簽。
procedure TWriter.WriteSignature;
begin
Write(FilerSignature, SizeOf(FilerSignature));
end;
FilerStgnature是字符串常量,其值為“TPF0”,代表對象標簽。
WritePrefix方法用于在寫入部件前寫入ffInherited和ffChildPos標志,這些標志表示部件的繼承特征和創建序值特征。
procedure TWriter.WritePrefix(Flags: TFilerFlags; AChildPos: Integer);
var
Prefix: Byte;
begin
if Flags <> [] then
begin
Prefix := $F0 or Byte(Flags);
Write(Prefix, SizeOf(Prefix));
if ffChildPos in Flags then WriteInteger(AChildPos);
end;
end;
如果ffChildPos置位,則存入部件在Owner中的創建序值。更詳細的信息請參閱TReader的ReadPrefix方法。
WriteComponent方法往流中寫入部件。
procedure TWriter.WriteComponent(Component: TComponent);
function FindAncestor(const Name: string): TComponent;
begin
…
end;
begin
Include(Component.FComponentState, csWriting);
if Assigned(FAncestorList) then
Ancestor := FindAncestor(Component.Name);
Component.WriteState(Self);
Exclude(Component.FComponentState, csWriting);
end;
方法中用Component的WritState方法寫入部件的屬性。在寫入之前將Component.FComponentState置為csWriting寫入完后再將csWriting復位。
WriteDescendant是根據祖先AAncestor的情況寫入部件Root。
procedure TWriter.WriteDescendent(Root: TComponent; AAncestor: TComponent);
begin
FRootAncestor := AAncestor;
FAncestor := AAncestor;
FRoot := Root;
WriteSignature;
WriteComponent(Root);
end;
方法先調用WriteSignature方法寫入Filer對象標簽。然后調用WriteComponent將部件Root寫入流。
WriteRootComponent方法則是調用WriteDescendant方法寫入部件,只是將后者的Ancestor參數以nil值傳入。
procedure TWriter.WriteRootComponent(Root: TComponent);
begin
WriteDescendent(Root, nil);
end;
20.2.3 TReader對象
TReader對象是可實例化的用于從相聯系的流中讀取數據的Filer對象。TReader對象從TFiler繼承下來,除了從TFiler繼承的屬性和方法外,TReader聲明了不少屬性、方法和事件。
Owner和Parent屬性用于表示從Reader對象的流中讀取的部件的擁有者和雙親結點。OnError,OnFindMethod和OnSetName事件使應用程序在運行中讀數據時能定制響應方式。除了覆蓋了一些從TFiler對象中繼承的方法外,TReader對象還定義大量的讀不同類型的數據和觸發事件的方法。
20.2.3.1 TReader對象的屬性和方法
1. Owner屬性
聲明:property Owner: TComponent;
Reader對象的Owner屬性存儲了將用來給從Reader的流中讀出的部件的Owner屬性賦值的部件。
2. Parent屬性
聲明:property Parent: TComponent;
Parent屬性存儲將用來給從Reader的流中讀出所有控制的Parent屬性賦值的部件。
3. Position屬性
聲明:propertion: Longint;
Reader對象的Position屬性表示相聯的流中讀的當前位置。Position的值還應包括讀緩沖區的大小。對于Reader 對象,Position的值大于流的Position 的值。如果將Position的值設得超過當前緩沖區,將引起調用FlushBuffer。
4. BeginReferences方法
聲明:procedure BeginReferences;
BeginReferences方法啟動一連串關于讀部件的命令,這些部件包含相互間的交叉引用。在使用上通常和FixupReferences和EndReferences一起放在Try…finally程序塊中。
在調用了BeginReferences后,Reader對象創建讀取所有對象和名字的列表。所有的獨立對象被讀出后,調用FixupReferences方法將名字的相互從流中轉移到對象實例中。最后調用EndReferences方法釋放列表。
處理部件相互引用的程序塊形式如下:
BeginReferences; { 創建臨時列表 }
try
{ 讀出所有部件并將它們的名字放在一臨時列表中 }
…
FixupReferences; { 分 解 }
finally
EndReferences; { 釋放臨時列表 }
end;
5. FixUpReferences方法
聲明:procedure FixupReferences;
FixupReferences方法分解從流中讀出的存在各種相互依賴部件的引用關系。FixupReferences總在try…finally塊中并配合BeginReferences和EndReferences一起使用。
6. EndReferences方法
聲明:procedure EndReferences;
EndReferences方法終止處理相互引用的塊操作,釋放對象列表。它總配合BeginReferences和FixupReferences一起使用。
7. ReadListBegin方法
聲明:procedure ReadListBegin;
ReadListBegin方法從Reader對象相聯的流中讀取列表開始標志。如果流中緊接著要讀取的項目不是一個由WritelistBegin方法寫入的列表起始標志,ReadListBegin將引起一個讀異常事件。
通常在調用ReadlistBegin方法之后,緊跟著一個讀項目的循環,循環以EndfList方法返回True 終止條件。這時,預示流中的下一個項目是列表結束標志,需要調用ReadListEnd方法。
8. ReadListEnd方法
聲明:procedure ReadListEnd;
ReadListEnd 方法從流中讀取列表結束標志。如果所讀的項目不是一個列表結束標志,ReadListEnd方法引發一個EReadError異常事件。
9. EndOfList方法
聲明:function EndOfList: Boolean;
如果Reader對象讀到項目列表結果標志,EndOfList方法返回True。
TStrings對象在從Reader對象讀取項目列表時使用了ReadListBegin和ReadListEnd方法。下面的ReadData是TStrings的方法,用于在DefineProperties方面中讀string數據。
procedure TStrings.ReadData(Reader: TReader);
begin
Reader.ReadListBegin; { 讀列表開始標志 }
Clear; { 清除已有的字符串 }
while not Reader.EndOfList do { 只要還有數據 … }
Add(Reader.ReadString); { …讀一個字符串并將其加在列表中 }
Reader.ReadListEnd; { 越過列表結束標志 }
end;
10. ReadSignature方法
聲明:procedure ReadSignature;
ReadSignature方法從流中讀取部件之前首先調用ReadSignature方法。在載入對象之前檢測標簽。Reader對象就能防止疏忽大意,導致讀取無效或過時的數據。Filer標簽是四個字符,對于Delphi 2.0,該標簽是“TPF0”。
11. ReadPrefix方法
聲明:procedure ReadPrefix(var Plags: TFilerFlags; var AChild, Pos: Integer);
ReadPrefix方法的功能與ReadSignature的很相象,只不過它是讀取流中部件前面的標志(PreFix)。當一個Write對象將部件寫入流中時,它在部件前面預寫了兩個值,第一個值是指明部件是否是從祖先窗體中繼承的窗體和它在窗體中的位置是否重要的標志;第二個值指明它在祖先窗體創建次序。ReadComponent方法自動調用ReadPrefix。但如果需要獨立讀取部件的預讀標志,也可直接調用該方向。
12. OnFindMethod事件
聲明:property OnFindMethod: TFindMethodEvent;
OnFindMethod事件,發生在Reader對象讀取對象的方法指針時,屬性為方法指針的通常都是事件。
響應OnFindMethod事件的理由,通常是處理過程找不到方法的情況。在FindMethod方法沒有找到由Name指定的方法的情況下,如果它將OnFindMethod方法的Error 參數設為True,將引起ReadError異常事件;反之,將Error參數置為False,將防止FindMethod方法引發異常事件。
相關推薦:2010年9月計算機等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內蒙古 |