?? 051.htm
字號:
<p> </font><font face="Arial">SetSize</font><font face="宋體" lang="ZH-CN">方法消除內存流中包含的數據,并將內存流中內存池的大小設為</font><fontface="Arial">Size</font><font face="宋體" lang="ZH-CN">字節。如果</font><fontface="Arial">Size</font><font face="宋體" lang="ZH-CN">為零,是</font><fontface="Arial">SetSize</font><font face="宋體" lang="ZH-CN">方法將釋放已有的內存池,并將</font><fontface="Arial">Memory</font><font face="宋體" lang="ZH-CN">屬性置為</font><fontface="Arial">nil</font><font face="宋體" lang="ZH-CN">;否則,</font><fontface="Arial">SetSize</font><font face="宋體" lang="ZH-CN">方法將內存池大小調整為</font><fontface="Arial">Size</font><font face="宋體" lang="ZH-CN">。</font><font face="Arial"></p><p>4. Clear</font><font face="宋體" lang="ZH-CN">方法</p><p> 聲明:</font><font face="Arial">procedure Clear; </p><p>Clear</font><font face="宋體" lang="ZH-CN">方法釋放內存中的內存池,并將</font><fontface="Arial">Memory</font><font face="宋體" lang="ZH-CN">屬性置為</font><fontface="Arial">nil</font><font face="宋體" lang="ZH-CN">。在調用</font><fontface="Arial">Clear</font><font face="宋體" lang="ZH-CN">方法后,</font><fontface="Arial">Size</font><font face="宋體" lang="ZH-CN">和</font><font face="Arial">Position</font><fontface="宋體" lang="ZH-CN">屬性都為</font><font face="Arial">0</font><fontface="宋體" lang="ZH-CN">。</p><p> </font><font face="Arial">5. LoadFromStream</font><font face="宋體"lang="ZH-CN">方法</p><p> 聲明:</font><font face="Arial">procedure LoadFromStream(Stream: TStream); </p><p>LoadFromStream</font><font face="宋體" lang="ZH-CN">方法將</font><fontface="Arial">Stream</font><font face="宋體" lang="ZH-CN">指定的流中的全部內容復制到</font><fontface="Arial">MemoryStream</font><font face="宋體" lang="ZH-CN">中,復制過程將取代已有內容,使</font><fontface="Arial">MemoryStream</font><font face="宋體" lang="ZH-CN">成為</font><fontface="Arial">Stream</font><font face="宋體" lang="ZH-CN">的一份拷貝。</p><p> </font><font face="Arial">6. LoadFromFile</font><font face="宋體" lang="ZH-CN">方法</p><p> 聲明:</font><font face="Arial">procedure LoadFromFile(count FileName:String); </p><p>LoadFromFile</font><font face="宋體" lang="ZH-CN">方法將</font><font face="Arial">FileName</font><fontface="宋體" lang="ZH-CN">指定文件的所有內容復制到</font><font face="Arial">MemoryStream</font><fontface="宋體" lang="ZH-CN">中,并取代已有內容。調用</font><font face="Arial">LoadFromFile</font><fontface="宋體" lang="ZH-CN">方法后,</font><font face="Arial">MemoryStream</font><fontface="宋體" lang="ZH-CN">將成為文件內容在內存中的完整拷貝。</p><p> </font><font face="Arial"></p><p>20.1.5.2 TMemoryStream</font><font face="宋體" lang="ZH-CN">對象的實現原理</p><p> </p><p> </font><font face="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">從</font><fontface="Arial">TCustomMemoryStream</font><font face="宋體" lang="ZH-CN">對象直接繼承,因此可以享用</font><fontface="Arial">TCustomMemoryStream</font><font face="宋體" lang="ZH-CN">的屬性和方法。前面講過,</font><fontface="Arial">TCustomMemoryStream</font><font face="宋體" lang="ZH-CN">是用于內存中數據操作的抽象對象,它為</font><fontface="Arial">MemoryStream</font><font face="宋體" lang="ZH-CN">對象的實現提供了框架,框架中的內容還要由具體</font><fontface="Arial">MemoryStream</font><font face="宋體" lang="ZH-CN">對象去填充。</font><fontface="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">對象就是按動態內存管理的需要填充框架中的具體內容。下面介紹</font><fontface="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">對象的實現。</p><p> </font><font face="Arial">1. TMemoryStream</font><font face="宋體" lang="ZH-CN">屬性的實現</p><p> </font><font face="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">在其</font><fontface="Arial">protected</font><font face="宋體" lang="ZH-CN">部分增加了一個</font><fontface="Arial">Capacity</font><font face="宋體" lang="ZH-CN">屬性,該屬性決定了</font><fontface="Arial">MemoryStream</font><font face="宋體" lang="ZH-CN">所占動態內存的大小。</font><fontface="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">首先在</font><fontface="Arial">private</font><font face="宋體" lang="ZH-CN">部分聲明了</font><fontface="Arial">FCapacity</font><font face="宋體" lang="ZH-CN">變量作為存儲</font><fontface="Arial">Capacity</font><font face="宋體" lang="ZH-CN">屬性值的數據域,然后在</font><fontface="Arial">protected</font><font face="宋體" lang="ZH-CN">部分聲明了該屬性。在屬性聲明的讀控制部分簡單讀取</font><fontface="Arial">FCapacity</font><font face="宋體" lang="ZH-CN">的值,在寫控制處調用了方法</font><fontface="Arial">SetCapacity</font><font face="宋體" lang="ZH-CN">。該方法除了給</font><fontface="Arial">FCapacity</font><font face="宋體" lang="ZH-CN">賦值外還執行了修改</font><fontface="Arial">Capacity</font><font face="宋體" lang="ZH-CN">屬性所必需操作如狀態改變等。</p><p> 下面是屬性的實現:</p><p> </p><p></font><font face="Arial">TMemoryStream = class(TCustomMemoryStream)</p><p>private</p><p>FCapacity: Longint;</p><p>procedure SetCapacity(NewCapacity: Longint);</p><p>protected</p><p></font><font face="宋體" lang="ZH-CN">…</p><p></font><font face="Arial">property Capacity: Longint read FCapacity write SetCapacity;</p><p>public</p><p></font><font face="宋體" lang="ZH-CN">…</p><p></font><font face="Arial">end;</p><p></font> <font face="宋體" lang="ZH-CN"></p><p> 寫控制方法</font><font face="Arial">SetCapacity</font><font face="宋體"lang="ZH-CN">的實現是這樣的:</p><p> </p><p></font><font face="Arial">procedure TMemoryStream.SetCapacity(NewCapacity: Longint);</p><p>begin</p><p>SetPointer(Realloc(NewCapacity), FSize);</p><p>FCapacity := NewCapacity;</p><p>end;</p><p></font> <font face="宋體" lang="ZH-CN"></p><p> 在</font><font face="Arial">SetCapacity </font><font face="宋體" lang="ZH-CN">方法先是調用</font><fontface="Arial">Realloc</font><font face="宋體" lang="ZH-CN">重新分配內存,然后用</font><fontface="Arial">NewCapacity</font><font face="宋體" lang="ZH-CN">的值給</font><fontface="Arial">FCapacity</font><font face="宋體" lang="ZH-CN">賦值。</font><fontface="Arial">Realloc</font><font face="宋體" lang="ZH-CN">方法進行某些對象狀態的改變。</p><p> </font><font face="Arial">2. TMemoryStream</font><font face="宋體" lang="ZH-CN">對象方法的實現</p><p> ⑴</font><font face="Arial"> Realloc</font><font face="宋體" lang="ZH-CN">方法</p><p> </font><font face="Arial">Realloc</font><font face="宋體" lang="ZH-CN">方法是</font><fontface="Arial">TMemoryStream</font><font face="宋體" lang="ZH-CN">動態內存分配的核心,它的</font><fontface="Arial">SetSize</font><font face="宋體" lang="ZH-CN">、</font><font face="Arial">SetCapacity</font><fontface="宋體" lang="ZH-CN">等方法最終都是調用</font><font face="Arial">Realloc</font><fontface="宋體" lang="ZH-CN">進行內存的分配和初始化工作的。它的實現如下:</p><p> </p><p></font><font face="Arial">const</p><p>MemoryDelta = $2000; </p><p></font> <font face="Arial"></p><p>function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;</p><p>begin</p><p>if NewCapacity > 0 then</p><p>NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);</p><p>Result := Memory;</p><p>if NewCapacity <> FCapacity then</p><p>begin</font><font face="宋體" lang="ZH-CN"></p><p></font><font face="Arial">if NewCapacity = 0 then</font><font face="宋體"lang="ZH-CN"></p><p></font><font face="Arial">begin</p><p>GlobalFreePtr(Memory);</p><p>Result := nil;</p><p>end else</p><p>begin</p><p>if Capacity = 0 then</p><p>Result := GlobalAllocPtr(HeapAllocFlags, NewCapacity)</p><p>else</p><p>Result := GlobalReallocPtr(Memory, NewCapacity, HeapAllocFlags);</p><p>if Result = nil then raise EStreamError.CreateRes(SMemoryStreamError);</p><p>end;</p><p>end;</p><p>end;</p><p></font> <font face="宋體" lang="ZH-CN"></p><p> </font><font face="Arial">Realloc</font><font face="宋體" lang="ZH-CN">方法是以</font><fontface="Arial">8K</font><font face="宋體" lang="ZH-CN">為單位分配動態內存的,方法中的第一句</font><fontface="Arial">if</font><font face="宋體" lang="ZH-CN">語句就是執行該操作。如果傳入的</font><fontface="Arial">NewCapacity</font><font face="宋體" lang="ZH-CN">參數值為</font><fontface="Arial">0</font><font face="宋體" lang="ZH-CN">,則釋放流中的內存。</font><fontface="Arial">Realloc</font><font face="宋體" lang="ZH-CN">方法用</font><fontface="Arial">GLobal FreePtr</font><font face="宋體" lang="ZH-CN">函數釋放內存,用</font><fontface="Arial">GlobalAllocPtr</font><font face="宋體" lang="ZH-CN">分配內存,用</font><fontface="Arial">GlobalReallocPtr</font><font face="宋體" lang="ZH-CN">進行內存的重分配。如果原來的</font><fontface="Arial">Capacity</font><font face="宋體" lang="ZH-CN">屬性值為</font><fontface="Arial">0</font><font face="宋體" lang="ZH-CN">,則調用</font><fontface="Arial">Globa|AllocPtr</font><font face="宋體" lang="ZH-CN">否則調用</font><fontface="Arial">GlobalReallocPtr</font><font face="宋體" lang="ZH-CN">。最后如果</font><fontface="Arial">Result</font><font face="宋體" lang="ZH-CN">為</font><font face="Arial">nil</font><fontface="宋體" lang="ZH-CN">則觸發內存流錯的異常事件,否則返回指向分配的內存的指針。</p><p> ⑵</font><font face="Arial"> Write</font><font face="宋體" lang="ZH-CN">方法</p><p> </font><font face="Arial">Write</font><font face="宋體" lang="ZH-CN">方法從內存流內部緩沖池的當前位置開始寫入二進制數據。其實現如下:</p><p> </p><p></font><font face="Arial">function TMemoryStream.Write(const Buffer; Count: Longint):Longint;</p><p>var</p><p>Pos: Longint;</p><p>begin</p><p>if (FPosition >= 0) and (Count >= 0) then</p><p>begin</p><p>Pos := FPosition + Count;</p><p>if Pos > 0 then</p><p>begin</p><p>if Pos > FSize then</p><p>begin</p><p>if Pos > FCapacity then</p><p>SetCapacity(Pos);</p><p>FSize := Pos;</p><p>end;</p><p>System.Move(Buffer, Pointer(Longint(FMemory) + FPosition)^, Count);</p><p>FPosition := Pos;</p><p>Result := Count;</p><p>Exit;</p><p>end;</p><p>end;</p><p>Result := 0;</p><p>end;</p><p></font> <font face="宋體" lang="ZH-CN"></p><p> </font><font face="Arial">Buffer</font><font face="宋體" lang="ZH-CN">中存儲要寫入流的二進制數據,如果要寫入的數據的字節超出了流的內存池的大小,則調用</font><fontface="Arial">SetCapacity</font><font face="宋體" lang="ZH-CN">方法再分配內存,然后用內存復制函數將</font><fontface="Arial">Buffer</font><font face="宋體" lang="ZH-CN">中的數據復制到</font><fontface="Arial">FMemory</font><font face="宋體" lang="ZH-CN">中。接著移動位置指針,并返回寫入數據的字節數。分析這段程序可以知道,</font><fontface="Arial">FCapacity</font><font face="宋體" lang="ZH-CN">的值和</font><font
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -