?? 054.htm
字號:
face="宋體" lang="ZH-CN">對象多了一個</font><font face="Arial">FButPos</font><font
face="宋體" lang="ZH-CN">的編移量。</p>
<p> </font><font face="Arial">2. Defineproperty</font><font face="宋體"
lang="ZH-CN">和</font><font face="Arial">DefineBinaryproperty</font><font face="宋體"
lang="ZH-CN">方法的實現</font><font face="Arial"></p>
<p></font><font face="宋體" lang="ZH-CN">這兩個方法是虛方法,在</font><font
face="Arial">TFiler</font><font face="宋體" lang="ZH-CN">中是抽象方法,在</font><font
face="Arial">TReader</font><font face="宋體" lang="ZH-CN">和</font><font face="Arial">TWriter</font><font
face="宋體" lang="ZH-CN">對象中才有具體的實現。</p>
<p> 它們在</font><font face="Arial">TReader</font><font face="宋體" lang="ZH-CN">中的實現如下:</p>
<p> </p>
<p></font><font face="Arial">procedure TReader.DefineProperty(const Name: string;
ReadData: TReaderProc; </p>
<p>WriteData: TWriterProc; HasData: Boolean);</p>
<p>begin</p>
<p>if CompareText(Name, FPropName) = 0 then</p>
<p>begin</p>
<p>ReadData(Self);</p>
<p>FPropName := '';</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>procedure TReader.DefineBinaryProperty(const Name: string;</p>
<p>ReadData, WriteData: TStreamProc; HasData: Boolean);</p>
<p>var</p>
<p>Stream: TMemoryStream;</p>
<p>Count: Longint;</p>
<p>begin</p>
<p>if CompareText(Name, FPropName) = 0 then</p>
<p>begin</p>
<p>if ReadValue <> vaBinary 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">Dec(FBufPos);</p>
<p>SkipValue;</p>
<p>FCanHandleExcepts := True;</p>
<p>PropValueError;</p>
<p>end;</p>
<p>Stream := TMemoryStream.Create;</p>
<p>try</p>
<p>Read(Count, SizeOf(Count));</p>
<p>Stream.SetSize(Count);</p>
<p>Read(Stream.Memory^, Count);</p>
<p>FCanHandleExcepts := True;</p>
<p>ReadData(Stream);</p>
<p>finally</p>
<p>Stream.Free;</p>
<p>end;</p>
<p>FPropName := '';</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p></font><font face="宋體" lang="ZH-CN">在兩個方法都將</font><font face="Arial">Name</font><font
face="宋體" lang="ZH-CN">參數值與當前的屬性名比較,如果相同則進行讀操作。在</font><font
face="Arial">DefineBinaryproperty</font><font face="宋體" lang="ZH-CN">中,創建了一個內存流。先將數據讀到內存流中然后調用</font><font
face="Arial">ReadData</font><font face="宋體" lang="ZH-CN">讀取數據。</p>
<p> </font><font face="Arial">3. FlushBuffer</font><font face="宋體" lang="ZH-CN">的實現</p>
<p> </font><font face="Arial">FlushBuffer</font><font face="宋體" lang="ZH-CN">方法用于清除</font><font
face="Arial">Reader</font><font face="宋體" lang="ZH-CN">對象的內部緩沖區中的內容,保持</font><font
face="Arial">Reader</font><font face="宋體" lang="ZH-CN">對象和流在位置(</font><font
face="Arial">Position</font><font face="宋體" lang="ZH-CN">)上的同步,其實現如下:</p>
<p> </p>
<p></font><font face="Arial">procedure TReader.FlushBuffer;</p>
<p>begin</p>
<p>FStream.Position := FStream.Position - (FBufEnd - FBufPos);</p>
<p>FBufPos := 0;</p>
<p>FBufEnd := 0;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">4. 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">方法</p>
<p> 這三個方法都是用于從</font><font face="Arial">Reader</font><font
face="宋體" lang="ZH-CN">對象的流中讀取一連串的項目,并且這些項目都由</font><font
face="Arial">WriteListBegin</font><font face="宋體" lang="ZH-CN">寫入的標志標定開始和</font><font
face="Arial">WriteListEnd</font><font face="宋體" lang="ZH-CN">寫入標志,標定結束,在讀循環中用</font><font
face="Arial">EndOfList</font><font face="宋體" lang="ZH-CN">進行判斷。它們是在</font><font
face="Arial">Reader</font><font face="宋體" lang="ZH-CN">對象讀取流中數據時經常用于的。它們的實現如下:</p>
<p> </p>
<p></font><font face="Arial">procedure TReader.ReadListBegin;</p>
<p>begin</p>
<p>CheckValue(vaList);</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>procedure TReader.ReadListEnd;</p>
<p>begin</p>
<p>CheckValue(vaNull);</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>function TReader.EndOfList: Boolean;</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">Result := ReadValue = vaNull;</p>
<p>Dec(FBufPos);</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> 項目表開始標志是</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">VaList</font><font face="宋體"
lang="ZH-CN">和</font><font face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">都是枚舉類型</font><font
face="Arial">TValueType</font><font face="宋體" lang="ZH-CN">定義的常量。</p>
<p> 它們實現中調用的</font><font face="Arial">CheckValue</font><font
face="宋體" lang="ZH-CN">是</font><font face="Arial">TReader</font><font face="宋體"
lang="ZH-CN">的私有方法,其實現如下:</p>
<p> </p>
<p></font><font face="Arial">procedure TReader.CheckValue(Value: TValueType);</p>
<p>begin</p>
<p>if ReadValue <> Value then</p>
<p>begin</p>
<p>Dec(FBufPos);</p>
<p>SkipValue;</p>
<p>PropValueError;</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">CheckValue</font><font face="宋體" lang="ZH-CN">方法的功能是檢測緊接著要讀的值是否是</font><font
face="Arial">Value</font><font face="宋體" lang="ZH-CN">指定的類型。如果不是則跳過該項目并觸發一個</font><font
face="Arial">SInvalidPropertyValue</font><font face="宋體" lang="ZH-CN">錯誤。</p>
<p> </font><font face="Arial">EndOfList</font><font face="宋體" lang="ZH-CN">函數只是簡單地判斷下一字節是否是</font><font
face="Arial">VaNull</font><font face="宋體" lang="ZH-CN">將判斷結果返回,并將字節移回原來位置。</p>
<p> </font><font face="Arial">5. </font><font face="宋體" lang="ZH-CN">簡單數據類型讀方法的實現</p>
<p> 簡單數據類型指的是布爾型、字符型、整型、字符串型、浮點型、集合類型和標識符。將它們放在一起介紹是因為它們的實現方法類似。</p>
<p> 因為它們的實現都用到了</font><font face="Arial">ReadValue</font><font
face="宋體" lang="ZH-CN">方法,因此先來介紹</font><font face="Arial">ReadValue</font><font
face="宋體" lang="ZH-CN">方法的實現:</p>
<p> </p>
<p></font><font face="Arial">function TReader.ReadValue: TValueType;</p>
<p>begin</p>
<p>Read(Result, SizeOf(Result));</p>
<p>end; </p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> 該方法調用私有方法</font><font face="Arial">Read</font><font
face="宋體" lang="ZH-CN">,從</font><font face="Arial">Reader</font><font
face="宋體" lang="ZH-CN">對象流中讀一個字節,并移動位置指針。</p>
<p> </font><font face="Arial">ReadValue</font><font face="宋體" lang="ZH-CN">方法專門從流中讀取值的類型的,所有的數據讀寫方法中在讀取數據前都要調用</font><font
face="Arial">ReadValue</font><font face="宋體" lang="ZH-CN">方法判斷是否是所要讀的數據。如果是,則調用</font><font
face="Arial">Read</font><font face="宋體" lang="ZH-CN">方法讀取數據;否則觸發一個異常事件,下面看</font><font
face="Arial">Integer</font><font face="宋體" lang="ZH-CN">類型的讀方法:</p>
<p> </p>
<p></font><font face="Arial">function TReader.ReadInteger: Longint;</p>
<p>var</p>
<p>S: Shortint;</p>
<p>I: Smallint;</p>
<p>begin</p>
<p>case ReadValue of</p>
<p>vaInt8:</p>
<p>begin</p>
<p>Read(S, SizeOf(Shortint));</p>
<p>Result := S;</p>
<p>end;</p>
<p>vaInt16:</p>
<p>begin</p>
<p>Read(I, SizeOf(I));</p>
<p>Result := I;</p>
<p>end;</p>
<p>vaInt32:</p>
<p>Read(Result, SizeOf(Result));</p>
<p>else</p>
<p>PropValueError;</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p></font><font face="宋體" lang="ZH-CN">因為</font><font face="Arial">Delphi 2.0</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">位,因此讀取整型數據時分別作了判斷。</p>
<p> 布爾類型的數據是直接放在值類型標志上,如果類型為</font><font
face="Arial">VaTrue</font><font face="宋體" lang="ZH-CN">,則值為</font><font
face="Arial">True</font><font face="宋體" lang="ZH-CN">;如果類型為</font><font
face="Arial">VaFalse</font><font face="宋體" lang="ZH-CN">,則值為</font><font
face="Arial">False</font><font face="宋體" lang="ZH-CN">。</p>
<p> </p>
<p></font><font face="Arial">function TReader.ReadBoolean: Boolean;</p>
<p>begin</p>
<p>Result := ReadValue = vaTrue;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>ReadString</font><font face="宋體" lang="ZH-CN">方法也利用</font><font
face="Arial">ReadValue</font><font face="宋體" lang="ZH-CN">方法判斷是字符串還是長字符串。</p>
<p> </p>
<p></font><font face="Arial">function TReader.ReadString: string;</p>
<p>var</p>
<p>L: Integer;</p>
<p>begin</p>
<p>L := 0;</p>
<p>case ReadValue of</p>
<p>vaString:</p>
<p>Read(L, SizeOf(Byte));</p>
<p>vaLString:</p>
<p>Read(L, SizeOf(Integer));</p>
<p>else</p>
<p>PropValueError;</p>
<p>end;</p>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -