?? 053.htm
字號:
<p> </font><font face="Arial"></p>
<p>20.2.2.2 TWriter</font><font face="宋體" lang="ZH-CN">對象的實現</p>
<p> </p>
<p> </font><font face="Arial">TWriter</font><font face="宋體" lang="ZH-CN">對象提供了許多往流中寫各種類型數據的方法,這對于程序員來說是很重要的功能。</font><font
face="Arial">TWrite</font><font face="宋體" lang="ZH-CN">對象往流中寫數據是依據不同的數據采取不同的格式的。</font>
<font face="宋體" lang="ZH-CN">因此要掌握</font><font face="Arial">TWriter</font><font
face="宋體" lang="ZH-CN">對象的實現和應用方法,必須了解</font><font
face="Arial">Writer</font><font face="宋體" lang="ZH-CN">對象存儲數據的格式。</p>
<p> 首先要說明的是,每個</font><font face="Arial">Filer</font><font
face="宋體" lang="ZH-CN">對象的流中都包含有</font><font face="Arial">Filer</font><font
face="宋體" lang="ZH-CN">對象標簽。該標簽占四個字節其值為“</font><font
face="Arial">TPF0</font><font face="宋體" lang="ZH-CN">”。</font><font face="Arial">Filer</font><font
face="宋體" lang="ZH-CN">對象為</font><font face="Arial">WriteSignature</font><font
face="宋體" lang="ZH-CN">和</font><font face="Arial">ReadSignature</font><font
face="宋體" lang="ZH-CN">方法存取該標簽。該標簽主要用于</font><font
face="Arial">Reader</font><font face="宋體" lang="ZH-CN">對象讀數據</font><font
face="Arial">(</font><font face="宋體" lang="ZH-CN">部件等</font><font face="Arial">)</font><font
face="宋體" lang="ZH-CN">時,指導讀操作。</p>
<p> 其次,</font><font face="Arial">Writer</font><font face="宋體" lang="ZH-CN">對象在存儲數據前都要留一個字節的標志位,以指出后面存放的是什么類型的數據。該字節為</font><font
face="Arial">TValueType</font><font face="宋體" lang="ZH-CN">類型的值。</font><font
face="Arial">TValueType</font><font face="宋體" lang="ZH-CN">是枚舉類型,占一個字節空間,其定義如下:</p>
<p> </p>
<p> </font><font face="Arial">TValueType = (VaNull, VaList, VaInt8, VaInt16, VaInt32,
VaEntended, VaString, VaIdent, </p>
<p>VaFalse, VaTrue, VaBinary, VaSet, VaLString, VaNil, VaCollection); </p>
<p></font> <font face="Arial"></p>
<p></font><font face="宋體" lang="ZH-CN">因此,對</font><font face="Arial">Writer</font><font
face="宋體" lang="ZH-CN">對象的每一個寫數據方法,在實現上,都要先寫標志位再寫相應的數據</font><font
face="Arial">;</font><font face="宋體" lang="ZH-CN">而</font><font face="Arial">Reader</font><font
face="宋體" lang="ZH-CN">對象的每一個讀數據方法都要先讀標志位進行判斷,如果符合就讀數據,否則產生一個讀數據無效的異常事件。</font><font
face="Arial">VaList</font><font face="宋體" lang="ZH-CN">標志有著特殊的用途,它是用來標識后面將有一連串類型相同的項目,而標識連續項目結束的標志是</font><font
face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">。因此,在</font><font
face="Arial">Writer</font><font face="宋體" lang="ZH-CN">對象寫連續若干個相同項目時,先用</font><font
face="Arial">WriteListBegin</font><font face="宋體" lang="ZH-CN">寫入</font><font
face="Arial">VaList</font><font face="宋體" lang="ZH-CN">標志,寫完數據項目后,再寫出</font><font
face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">標志;而讀這些數據時,以</font><font
face="Arial">ReadListBegin</font><font face="宋體" lang="ZH-CN">開始,</font><font
face="Arial">ReadListEnd</font><font face="宋體" lang="ZH-CN">結束,中間用</font><font
face="Arial">EndofList</font><font face="宋體" lang="ZH-CN">函數判斷是否有</font><font
face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">標志。</p>
<p> 下面就介紹它們的實現。</p>
<p> </font><font face="Arial">1. TWriter</font><font face="宋體" lang="ZH-CN">對象屬性的實現</p>
<p> </font><font face="Arial">TWriter</font><font face="宋體" lang="ZH-CN">對象直接從</font><font
face="Arial">TFiler</font><font face="宋體" lang="ZH-CN">對象繼承,它只增加了</font><font
face="Arial">Position</font><font face="宋體" lang="ZH-CN">和</font><font face="Arial">RootAncestor</font><font
face="宋體" lang="ZH-CN">屬性。</font><font face="Arial"></p>
<p>RootAncestor</font><font face="宋體" lang="ZH-CN">屬性在</font><font face="Arial">private</font><font
face="宋體" lang="ZH-CN">部分有數據域</font><font face="Arial">FRootAncestor</font><font
face="宋體" lang="ZH-CN">存入其值。在屬性定義的讀與控制上都是直接讀取該值。</p>
<p> </font><font face="Arial">Position</font><font face="宋體" lang="ZH-CN">屬性的定義中包含了兩個讀寫控制方法:</font><font
face="Arial">GetPosition</font><font face="宋體" lang="ZH-CN">和</font><font
face="Arial">SetPosition</font><font face="宋體" lang="ZH-CN">:</p>
<p> </p>
<p></font><font face="Arial">TWriter = class(TFiler)</p>
<p>private</p>
<p>FRootAncestor: TComponent;</p>
<p></font><font face="宋體" lang="ZH-CN">…</p>
<p></font><font face="Arial">function GetPosition: Longint;</p>
<p>procedure SetPosition(Value: Longint);</p>
<p>public</p>
<p></font><font face="宋體" lang="ZH-CN">…</p>
<p></font><font face="Arial">property Position: Longint read GetPosition write
SetPosition;</p>
<p>property RootAncestor: TComponent read FRootAncestor write FRootAncestor;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>GetPosition</font><font face="宋體" lang="ZH-CN">和</font><font face="Arial">SetPosition</font><font
face="宋體" lang="ZH-CN">方法實現如下:</p>
<p> </p>
<p></font><font face="Arial">function TWriter.GetPosition: Longint;</p>
<p>begin</p>
<p>Result := FStream.Position + FBufPos;</p>
<p>end;</font><font face="宋體" lang="ZH-CN"></p>
<p> </p>
<p></font><font face="Arial">procedure TWriter.SetPosition(Value: Longint);</p>
<p>var</p>
<p>StreamPosition: Longint;</p>
<p>begin</p>
<p>StreamPosition := FStream.Position;</p>
<p>{ </font><font face="宋體" lang="ZH-CN">只清除越界的緩沖區</font> <font
face="Arial">}</p>
<p>if (Value < StreamPosition) or (Value > StreamPosition + FBufPos) then</p>
<p>begin</p>
<p>WriteBuffer;</p>
<p>FStream.Position := Value;</p>
<p>end</p>
<p>else FBufPos := Value - StreamPosition;</p>
<p>end; </p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">WriteBuffer</font><font face="宋體" lang="ZH-CN">是</font><font
face="Arial">TWriter</font><font face="宋體" lang="ZH-CN">對象定義的私有方法,它的作用是將</font><font
face="Arial">Writer </font><font face="宋體" lang="ZH-CN">對象內部緩沖區中的有效數據寫入流中,并將</font><font
face="Arial">FBufPos</font><font face="宋體" lang="ZH-CN">置為</font><font
face="Arial">0</font><font face="宋體" lang="ZH-CN">。</font><font face="Arial">Writer</font><font
face="宋體" lang="ZH-CN">對象的</font><font face="Arial">FlushBuffer</font><font
face="宋體" lang="ZH-CN">對象就是用</font><font face="Arial">WriteBuffer</font><font
face="宋體" lang="ZH-CN">方法刷新緩沖區。</p>
<p> 在</font><font face="Arial">SetPosition</font><font face="宋體" lang="ZH-CN">方法中,如果</font><font
face="Arial">Value</font><font face="宋體" lang="ZH-CN">值超出了邊界</font><font
face="Arial">(FStream.Position</font><font face="宋體" lang="ZH-CN">,</font><font
face="Arial">FStream.Position + FBufPos)</font><font face="宋體" lang="ZH-CN">,就將緩沖區中的內容寫入流,重新設置緩沖區在流中的相對位置;否則,就只是移動</font><font
face="Arial">FBufPos</font><font face="宋體" lang="ZH-CN">指針。</p>
<p> </font><font face="Arial">2. TWriter</font><font face="宋體" lang="ZH-CN">方法的實現</p>
<p> ⑴</font><font face="Arial"> WriteListBegin</font><font face="宋體"
lang="ZH-CN">和</font><font face="Arial">WriteListEnd</font><font face="宋體"
lang="ZH-CN">的實現</p>
<p> 這兩個方法都是用于寫連續若干個相同類型的值。</font><font
face="Arial">WriteListBegin</font><font face="宋體" lang="ZH-CN">寫入</font><font
face="Arial">VaList</font><font face="宋體" lang="ZH-CN">標志,</font><font
face="Arial">WriteListEnd</font><font face="宋體" lang="ZH-CN">寫入</font><font
face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">標志。</p>
<p> </p>
<p></font><font face="Arial">procedure TWriter.WriteListBegin;</p>
<p>begin</p>
<p>WriteValue(vaList);</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>procedure TWriter.WriteListEnd;</p>
<p>begin</p>
<p>WriteValue(vaNull);</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> 這兩個方法都調用</font><font face="Arial">TWriter</font><font
face="宋體" lang="ZH-CN">對象的</font><font face="Arial">WriteValue</font><font
face="宋體" lang="ZH-CN">方法,該方法主要用于寫入</font><font face="Arial">TValueType</font><font
face="宋體" lang="ZH-CN">類型的值。</p>
<p> </p>
<p></font><font face="Arial">procedure TWriter.WriteValue(Value: TValueType);</p>
<p>begin</p>
<p>Write(Value, SizeOf(Value)); </p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> ?、?lt;/font><font face="Arial"> </font><font face="宋體" lang="ZH-CN">簡單數據類型的寫入</p>
<p> 簡單數據類型指的是整型、字符型、字符串型、浮點型、布爾型等。</font><font
face="Arial">TWriter</font><font face="宋體" lang="ZH-CN">對象都定義了相應的寫入方法。</p>
<p> </font><font face="Arial">WriteInteger</font><font face="宋體" lang="ZH-CN">方法用于寫入整型數據。</p>
<p> </p>
<p></font><font face="Arial">procedure TWriter.WriteInteger(Value: Longint);</p>
<p>begin</p>
<p>if (Value >= -128) and (Value <= 127) then</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">begin</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">WriteValue(vaInt8);</p>
<p>Write(Value, SizeOf(Shortint));</p>
<p>end else</p>
<p>if (Value >= -32768) and (Value <= 32767) then</p>
<p>begin</p>
<p>WriteValue(vaInt16);</p>
<p>Write(Value, SizeOf(Smallint));</p>
<p>end else</p>
<p>begin</p>
<p>WriteValue(vaInt32);</p>
<p>Write(Value, SizeOf(Longint));</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">WriteInteger</font><font face="宋體" lang="ZH-CN">方法將整型數據分為</font><font
face="Arial">8</font><font face="宋體" lang="ZH-CN">位、</font><font face="Arial">16</font><font
face="宋體" lang="ZH-CN">位和</font><font face="Arial">32</font><font face="宋體"
lang="ZH-CN">位三種,并分別用</font><font face="Arial">vaInt8</font><font
face="宋體" lang="ZH-CN">、</font><font face="Arial">vaInt16</font><font face="宋體"
lang="ZH-CN">和</font><font face="Arial">VaInt32</font><font face="宋體" lang="ZH-CN">。</p>
<p> </font><font face="Arial">WriteBoolean</font><font face="宋體" lang="ZH-CN">用于寫入布爾型數據:</p>
<p> </p>
<p></font><font face="Arial">procedure TWriter.WriteBoolean(Value: Boolean);</p>
<p>begin</p>
<p>if Value then</p>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -