function THandleStreamWrite(const Buffer; Count: Longint) Longint;
begin
Result := FileWrite(FHandle Buffer Count)
if Result = then Result := ;
end;
Seek方法调用FileSeek函数实现文件指针的移动其实现如下
function THandleStreamSeek(Offset: Longint; Origin: Word) Longint;
begin
Result := FileSeek(FHandle Offset Origin)
end;
TFileStream对象
TFileStream对象是在磁盘文件上存储数据的Stream对象TFileStream是从THandleStream继承下来的它和THandleStream一样都是实现文件的存取操作不同之处在于THandleStream用句柄访问文件而TFileStream用文件名访问文件实际上TFileStream是THandleStream上的一层包装其内核是THandleStream的属性和方法
TFileStream中没有增加新的属性和方法它只是覆盖了的构造方法Create和析构方法Destory在Create方法中带两个参数FileName和ModeFileName描述要创建或打开的文件名而Mode描述文件模式如fmCreatefmOpenRead和fmOpenWrite等Create方法首先使用FileCreate或FileOpen函数创建或打开名为FileName的文件再将得到的文件句柄赋给FHandleTFileStream的文件读写操作都是由从THandleStream继承的Read
var
Stream: TStream;
begin
Stream := TFileStreamCreate(FileName fmCreate)
try
SaveToStream(Stream)
finally
StreamFree;
end;
end;
在Delphi 的许多对象的SaveToStream 和SaveToFileLoadFromStream和LoadFromFile方法的实现都有类似的嵌套结构
TMemoryStream对象
TMemoryStream对象是一个管理动态内存中的数据的Stream对象它是从TCustomMemoryStream中继承下来的除了从TCustomMemoryStream中继承的属性和方法外它还增加和覆盖了一些用于从磁盘文件和其它注台读数据的方法它还提供了写入消除内存内容的动态内存管理方法下面介绍它的这些属性和方法
TMemoryStream的属性和方法
Capacity属性
声明
property Copacity: Longint;
Capacity属性决定了分配给内存流的内存池的大小这与Size属性有些不同Size属性是描述流中数据的大小在程序中可以将Capacity 的值设置的比数据所需最大内存大一些这样可以避免频繁地重新分配
Realloc方法
声明
function Realloc(var NewCapacity: Longint)
Pointer; virtual;
Realloc方法以K为单位分配动态内存内存的大小由NewCapacity指定函数返回指向所分配内存的指针
SetSize方法
SetSize方法消除内存流中包含的数据并将内存流中内存池的大小设为Size字节如果Size为零是SetSize方法将释放已有的内存池并将Memory属性置为nil;否则SetSize方法将内存池大小调整为Size
Clear方法
声明
procedure Clear;
Clear方法释放内存中的内存池并将Memory属性置为nil在调用Clear方法后Size和Position属性都为
LoadFromStream方法
声明
procedure LoadFromStream(Stream: TStream)
LoadFromStream方法将Stream指定的流中的全部内容复制到MemoryStream中复制过程将取代已有内容使MemoryStream成为Stream的一份拷贝
LoadFromFile方法
声明
procedure LoadFromFile(count FileName: String)
LoadFromFile方法将FileName指定文件的所有内容复制到MemoryStream中并取代已有内容调用LoadFromFile方法后MemoryStream将成为文件内容在内存中的完整拷贝
TMemoryStream对象的实现原理
TMemoryStream从TCustomMemoryStream对象直接继承因此可以享用TCustomMemoryStream的属性和方法前面讲过TCustomMemoryStream是用于内存中数据操作的抽象对象它为MemoryStream对象的实现提供了框架框架中的内容还要由具体MemoryStream对象去填充TMemoryStream对象就是按动态内存管理的需要填充框架中的具体内容下面介绍TMemoryStream对象的实现
TMemoryStream属性的实现
TMemoryStream在其protected部分增加了一个Capacity属性该属性决定了MemoryStream所占动态内存的大小TMemoryStream首先在private部分声明了FCapacity变量作为存储Capacity属性值的数据域然后在protected部分声明了该属性在属性声明的读控制部分简单读取FCapacity的值在写控制处调用了方法SetCapacity该方法除了给FCapacity赋值外还执行了修改Capacity属性所必需操作如状态改变等
下面是属性的实现
TMemoryStream = class(TCustomMemoryStream)
private
FCapacity: Longint;
procedure SetCapacity(NewCapacity: Longint)
protected
…
property Capacity: Longint read FCapacity write SetCapacity;
public
…
end;
写控制方法SetCapacity的实现是这样的
procedure TMemoryStreamSetCapacity(NewCapacity: Longint)
begin
SetPointer(Realloc(NewCapacity) FSize)
FCapacity := NewCapacity;
end;
在SetCapacity 方法先是调用Realloc重新分配内存然后用NewCapacity的值给FCapacity赋值Realloc方法进行某些对象状态的改变
TMemoryStream对象方法的实现
⑴ Realloc方法
Realloc方法是TMemoryStream动态内存分配的核心它的SetSizeSetCapacity等方法最终都是调用Realloc进行内存的分配和初始化工作的它的实现如下
const
MemoryDelta = $;
function TMemoryStreamRealloc(var NewCapacity: Longint) Pointer;
begin
if NewCapacity > then
NewCapacity := (NewCapacity + (MemoryDelta )) and not (MemoryDelta )
Result := Memory;
if NewCapacity <> FCapacity then
begin
if NewCapacity = then
begin
GlobalFreePtr(Memory)
Result := nil;
end else
begin
if Capacity = then
Result := GlobalAllocPtr(HeapAllocFlags NewCapacity)
else
Result := GlobalReallocPtr(Memory NewCapacity HeapAllocFlags)
if Result = nil then raise EStreamErrorCreateRes(SMemoryStreamError)
end;
end;
end;
Realloc方法是以K为单位分配动态内存的方法中的第一句if语句就是执行该操作如果传入的NewCapacity参数值为则释放流中的内存Realloc方法用GLobal FreePtr函数释放内存用GlobalAllocPtr分配内存用GlobalReallocPtr进行内存的重分配如果原来的Capacity属性值为则调用Globa|AllocPtr否则调用GlobalReallocPtr最后如果Result为nil则触发内存流错的异常事件否则返回指向分配的内存的指针
[] [] [] [] []