📄 051.htm
字号:
<p> </p>
<p> </font><font face="Arial">1. Capacity</font><font face="宋体" lang="ZH-CN">属性</p>
<p> 声明:</font><font face="Arial">property Copacity: Longint; </p>
<p>Capacity</font><font face="宋体" lang="ZH-CN">属性决定了分配给内存流的内存池的大小。这与</font><font
face="Arial">Size</font><font face="宋体" lang="ZH-CN">属性有些不同。</font><font
face="Arial">Size</font><font face="宋体" lang="ZH-CN">属性是描述流中数据的大小。在程序中可以将</font><font
face="Arial">Capacity </font><font face="宋体" lang="ZH-CN">的值设置的比数据所需最大内存大一些,这样可以避免频繁地重新分配。</p>
<p> </font><font face="Arial">2. Realloc</font><font face="宋体" lang="ZH-CN">方法</p>
<p> 声明:</font><font face="Arial">function Realloc(var NewCapacity: Longint):
Pointer; virtual; </p>
<p>Realloc</font><font face="宋体" lang="ZH-CN">方法,以</font><font face="Arial">8K</font><font
face="宋体" lang="ZH-CN">为单位分配动态内存,内存的大小由</font><font
face="Arial">NewCapacity</font><font face="宋体" lang="ZH-CN">指定,函数返回指向所分配内存的指针。</p>
<p> </font><font face="Arial">3. SetSize</font><font face="宋体" lang="ZH-CN">方法</p>
<p> </font><font face="Arial">SetSize</font><font face="宋体" lang="ZH-CN">方法消除内存流中包含的数据,并将内存流中内存池的大小设为</font><font
face="Arial">Size</font><font face="宋体" lang="ZH-CN">字节。如果</font><font
face="Arial">Size</font><font face="宋体" lang="ZH-CN">为零,是</font><font
face="Arial">SetSize</font><font face="宋体" lang="ZH-CN">方法将释放已有的内存池,并将</font><font
face="Arial">Memory</font><font face="宋体" lang="ZH-CN">属性置为</font><font
face="Arial">nil</font><font face="宋体" lang="ZH-CN">;否则,</font><font
face="Arial">SetSize</font><font face="宋体" lang="ZH-CN">方法将内存池大小调整为</font><font
face="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><font
face="Arial">Memory</font><font face="宋体" lang="ZH-CN">属性置为</font><font
face="Arial">nil</font><font face="宋体" lang="ZH-CN">。在调用</font><font
face="Arial">Clear</font><font face="宋体" lang="ZH-CN">方法后,</font><font
face="Arial">Size</font><font face="宋体" lang="ZH-CN">和</font><font face="Arial">Position</font><font
face="宋体" lang="ZH-CN">属性都为</font><font face="Arial">0</font><font
face="宋体" 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><font
face="Arial">Stream</font><font face="宋体" lang="ZH-CN">指定的流中的全部内容复制到</font><font
face="Arial">MemoryStream</font><font face="宋体" lang="ZH-CN">中,复制过程将取代已有内容,使</font><font
face="Arial">MemoryStream</font><font face="宋体" lang="ZH-CN">成为</font><font
face="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><font
face="宋体" lang="ZH-CN">指定文件的所有内容复制到</font><font face="Arial">MemoryStream</font><font
face="宋体" lang="ZH-CN">中,并取代已有内容。调用</font><font face="Arial">LoadFromFile</font><font
face="宋体" lang="ZH-CN">方法后,</font><font face="Arial">MemoryStream</font><font
face="宋体" 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><font
face="Arial">TCustomMemoryStream</font><font face="宋体" lang="ZH-CN">对象直接继承,因此可以享用</font><font
face="Arial">TCustomMemoryStream</font><font face="宋体" lang="ZH-CN">的属性和方法。前面讲过,</font><font
face="Arial">TCustomMemoryStream</font><font face="宋体" lang="ZH-CN">是用于内存中数据操作的抽象对象,它为</font><font
face="Arial">MemoryStream</font><font face="宋体" lang="ZH-CN">对象的实现提供了框架,框架中的内容还要由具体</font><font
face="Arial">MemoryStream</font><font face="宋体" lang="ZH-CN">对象去填充。</font><font
face="Arial">TMemoryStream</font><font face="宋体" lang="ZH-CN">对象就是按动态内存管理的需要填充框架中的具体内容。下面介绍</font><font
face="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><font
face="Arial">protected</font><font face="宋体" lang="ZH-CN">部分增加了一个</font><font
face="Arial">Capacity</font><font face="宋体" lang="ZH-CN">属性,该属性决定了</font><font
face="Arial">MemoryStream</font><font face="宋体" lang="ZH-CN">所占动态内存的大小。</font><font
face="Arial">TMemoryStream</font><font face="宋体" lang="ZH-CN">首先在</font><font
face="Arial">private</font><font face="宋体" lang="ZH-CN">部分声明了</font><font
face="Arial">FCapacity</font><font face="宋体" lang="ZH-CN">变量作为存储</font><font
face="Arial">Capacity</font><font face="宋体" lang="ZH-CN">属性值的数据域,然后在</font><font
face="Arial">protected</font><font face="宋体" lang="ZH-CN">部分声明了该属性。在属性声明的读控制部分简单读取</font><font
face="Arial">FCapacity</font><font face="宋体" lang="ZH-CN">的值,在写控制处调用了方法</font><font
face="Arial">SetCapacity</font><font face="宋体" lang="ZH-CN">。该方法除了给</font><font
face="Arial">FCapacity</font><font face="宋体" lang="ZH-CN">赋值外还执行了修改</font><font
face="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><font
face="Arial">Realloc</font><font face="宋体" lang="ZH-CN">重新分配内存,然后用</font><font
face="Arial">NewCapacity</font><font face="宋体" lang="ZH-CN">的值给</font><font
face="Arial">FCapacity</font><font face="宋体" lang="ZH-CN">赋值。</font><font
face="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><font
face="Arial">TMemoryStream</font><font face="宋体" lang="ZH-CN">动态内存分配的核心,它的</font><font
face="Arial">SetSize</font><font face="宋体" lang="ZH-CN">、</font><font face="Arial">SetCapacity</font><font
face="宋体" lang="ZH-CN">等方法最终都是调用</font><font face="Arial">Realloc</font><font
face="宋体" 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><font
face="Arial">8K</font><font face="宋体" lang="ZH-CN">为单位分配动态内存的,方法中的第一句</font><font
face="Arial">if</font><font face="宋体" lang="ZH-CN">语句就是执行该操作。如果传入的</font><font
face="Arial">NewCapacity</font><font face="宋体" lang="ZH-CN">参数值为</font><font
face="Arial">0</font><font face="宋体" lang="ZH-CN">,则释放流中的内存。</font><font
face="Arial">Realloc</font><font face="宋体" lang="ZH-CN">方法用</font><font
face="Arial">GLobal FreePtr</font><font face="宋体" lang="ZH-CN">函数释放内存,用</font><font
face="Arial">GlobalAllocPtr</font><font face="宋体" lang="ZH-CN">分配内存,用</font><font
face="Arial">GlobalReallocPtr</font><font face="宋体" lang="ZH-CN">进行内存的重分配。如果原来的</font><font
face="Arial">Capacity</font><font face="宋体" lang="ZH-CN">属性值为</font><font
face="Arial">0</font><font face="宋体" lang="ZH-CN">,则调用</font><font
face="Arial">Globa|AllocPtr</font><font face="宋体" lang="ZH-CN">否则调用</font><font
face="Arial">GlobalReallocPtr</font><font face="宋体" lang="ZH-CN">。最后如果</font><font
face="Arial">Result</font><font face="宋体" lang="ZH-CN">为</font><font face="Arial">nil</font><font
face="宋体" 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -