庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>Delphi语言>基础教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

开发Delphi对象式数据管理功能(二)

 作者:本站收集   日期:2005-3-29
字号选择〖 〗/ 双击滚屏 单击停止   

20.1.2.1 THandleStream的属性的方法:

 

  1. Handle属性

  声明:property Handle: Integer;

Handle属性提供了对文件句柄的只读访问,该句柄由THandleStream的构造方法Create传入。因此除了用THandleStream提供的方法外,也可以用文件管理函数对句柄进行操作。实际上,THandleStream的方法在实现上也是运用文件管理函数进行实际的读写操作。

  2. Create方法

  声明:constructor Create(AHandle: Integer);

  Create方法使用传入的Handle参数创建一个与特定文件句柄相联的THandleStream对象,并且将AHandle赋给流的Handle属性。

 

  3. ReadWriteSeek方法

  这三个方法是TStream的虚方法,只是在THandleStream 中覆盖了这三个方法,以实现特定媒介──文件的数据存取。后面会详细介绍这三个方法的实现。

 

20.1.2.2 THandleStream的实现原理

 

  THandleStream是从TStream继承来的,因此可以共用TStream中的属性和大多数方法。THandleStream在实现上主要是增加了一个属性Handle和覆盖了CreateReadWriteSeek四个方法。

  1. 属性的实现

  Handle属性的实现正如Delphi大多数属性的实现那样,先在对象定义的private部分声明一个存放数据的变量FHandle,然后在定义的public部分声明属性Handle,其中属性定义的读写控制部分加上只读控制,读控制只是直接读取FHandle变量的值,其实现如下:

 

THandleStream = class(TStream)

private

FHandle: Integer;

public

property Handle: Integer read FHandle;

end;

 

2. 方法的实现

  THandleStreamCreate方法,以AHandle作为参数,在方法里面只是简单的将AHandle的值赋给FHandle,其实现如下:

 

constructor THandleStream.Create(AHandle: Integer);

begin

FHandle := AHandle;

end;

 

  为实现针对文件的数据对象存储,THandleStreamReadWriteSeek方法覆盖了TStream中的相应方法。它们的实现都调用了Windows的文件管理函数

  Read方法调用FileRead函数实现文件读操作,其实现如下:

 

function THandleStream.Read(var Buffer; Count: Longint): Longint;

begin

Result := FileRead(FHandle, Buffer, Count);

if Result = -1 then Result := 0;

end;

 

  Write方法调用FileWrite函数实现文件写操作,其实现如下:

 

function THandleStream.Write(const Buffer; Count: Longint): Longint;

begin

Result := FileWrite(FHandle, Buffer, Count);

if Result = -1 then Result := 0;

end;

 

  Seek方法调用FileSeek函数实现文件指针的移动,其实现如下:

 

function THandleStream.Seek(Offset: Longint; Origin: Word): Longint;

begin

Result := FileSeek(FHandle, Offset, Origin);

end;

 

20.1.3 TFileStream对象

 

  TFileStream对象是在磁盘文件上存储数据Stream对象。TFileStream是从THandleStream继承下来的,它和THandleStream一样都是实现文件的存取操作。不同之处在于THandleStream用句柄访问文件,而TFileStream用文件名访问文件。实际上TFileStreamTHandleStream上的一层包装,其内核是THandleStream的属性和方法。

  TFileStream中没有增加新的属性和方法。它只是覆盖了的构造方法Create和析构方法Destory。在Create方法中带两个参数FileNameModeFileName描述要创建或打开的文件名,而Mode描述文件模式如fmCreatefmOpenReadfmOpenWrite等。Create方法首先使用FileCreateFileOpen函数创建或打开名为FileName的文件,再将得到的文件句柄赋给FHandleTFileStream的文件读写操作都是由从THandleStream继承的Read

var

Stream: TStream;

begin

Stream := TFileStream.Create(FileName, fmCreate);

try

SaveToStream(Stream);

finally

Stream.Free;

end;

end;

 

  在Delphi 的许多对象的SaveToStream SaveToFileLoadFromStreamLoadFromFile方法的实现都有类似的嵌套结构。

 

20.1.5 TMemoryStream对象

 

  TMemoryStream对象是一个管理动态内存中的数据Stream对象,它是从TCustomMemoryStream中继承下来的,除了从TCustomMemoryStream中继承的属性和方法外,它还增加和覆盖了一些用于从磁盘文件和其它注台读数据的方法。它还提供了写入、消除内存内容的动态内存管理方法。下面介绍它的这些属性和方法。

 

20.1.5.1 TMemoryStream的属性和方法

 

  1. Capacity属性

  声明:property Copacity: Longint;

Capacity属性决定了分配给内存流的内存池的大小。这与Size属性有些不同。Size属性是描述流中数据的大小。在程序中可以将Capacity 的值设置的比数据所需最大内存大一些,这样可以避免频繁地重新分配。

  2. Realloc方法

  声明:function Realloc(var NewCapacity: Longint): Pointer; virtual;

Realloc方法,以8K为单位分配动态内存内存的大小由NewCapacity指定,函数返回指向所分配内存的指针。

  3. SetSize方法

  SetSize方法消除内存流中包含的数据,并将内存流中内存池的大小设为Size字节。如果Size为零,是SetSize方法将释放已有的内存池,并将Memory属性置为nil;否则,SetSize方法将内存池大小调整为Size

4. Clear方法

  声明:procedure Clear;

Clear方法释放内存中的内存池,并将Memory属性置为nil。在调用Clear方法后,SizePosition属性都为0

  5. LoadFromStream方法

  声明:procedure LoadFromStream(Stream: TStream);

LoadFromStream方法将Stream指定的流中的全部内容复制到MemoryStream中,复制过程将取代已有内容,使MemoryStream成为Stream的一份拷贝。

  6. LoadFromFile方法

  声明:procedure LoadFromFile(count FileName: String);

LoadFromFile方法将FileName指定文件的所有内容复制到MemoryStream中,并取代已有内容。调用LoadFromFile方法后,MemoryStream将成为文件内容在内存中的完整拷贝。

 

20.1.5.2 TMemoryStream对象的实现原理

 

  TMemoryStreamTCustomMemoryStream对象直接继承,因此可以享用TCustomMemoryStream的属性和方法。前面讲过,TCustomMemoryStream是用于内存数据操作的抽象对象,它为MemoryStream对象的实现提供了框架,框架中的内容还要由具体MemoryStream对象去填充。TMemoryStream对象就是按动态内存管理的需要填充框架中的具体内容。下面介绍TMemoryStream对象的实现。

  1. 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 TMemoryStream.SetCapacity(NewCapacity: Longint);

begin

SetPointer(Realloc(NewCapacity), FSize);

FCapacity := NewCapacity;

end;

 

  在SetCapacity 方法先是调用Realloc重新分配内存,然后用NewCapacity的值给FCapacity赋值。Realloc方法进行某些对象状态的改变。

  2. TMemoryStream对象方法的实现

  ⑴ Realloc方法

  Realloc方法是TMemoryStream动态内存分配的核心,它的SetSizeSetCapacity等方法最终都是调用Realloc进行内存的分配和初始化工作的。它的实现如下:

 

const

MemoryDelta = $2000;

 

function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;

begin

if NewCapacity > 0 then

NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);

Result := Memory;

if NewCapacity <> FCapacity then

begin

if NewCapacity = 0 then

begin

GlobalFreePtr(Memory);

Result := nil;

end else

begin

if Capacity = 0 then

Result := GlobalAllocPtr(HeapAllocFlags, NewCapacity)

else

Result := GlobalReallocPtr(Memory, NewCapacity, HeapAllocFlags);

if Result = nil then raise EStreamError.CreateRes(SMemoryStreamError);

end;

end;

end;

 

  Realloc方法是以8K为单位分配动态内存的,方法中的第一句if语句就是执行该操作。如果传入的NewCapacity参数值为0,则释放流中的内存Realloc方法用GLobal FreePtr函数释放内存,用GlobalAllocPtr分配内存,用GlobalReallocPtr进行内存的重分配。如果原来的Capacity属性值为0,则调用Globa|AllocPtr否则调用GlobalReallocPtr。最后如果Resultnil则触发内存流错的异常事件,否则返回指向分配的内存的指针。

  ⑵ Write方法

  Write方法从内存流内部缓冲池的当前位置开始写入二进制数据。其实现如下:

 

function TMemoryStream.Write(const Buffer; Count: Longint): Longint;

var

Pos: Longint;

begin

if (FPosition >= 0) and (Count >= 0) then

begin

Pos := FPosition + Count;

if Pos > 0 then

begin

if Pos > FSize then

begin

if Pos > FCapacity then

SetCapacity(Pos);

FSize := Pos;

end;

System.Move(Buffer, Pointer(Longint(FMemory) + FPosition)^, Count);

FPosition := Pos;

Result := Count;

Exit;

end;

end;

Result := 0;

end;

 

  Buffer中存储要写入流的二进制数据,如果要写入的数据的字节超出了流的内存池的大小,则调用SetCapacity方法再分配内存,然后用内存复制函数Buffer中的数据复制到FMemory中。接着移动位置指针,并返回写入数据的字节数。分析这段程序可以知道,FCapacity的值和FSize的值是不同的。

  ⑶ Clear方法

  Clear方法消除内存流中的数据,将Memory属性置为nil,并将FSizeFPosition 的值设为0。其实现如下:

 

procedure TMemoryStream.Clear;

begin

SetCapacity(0);

FSize := 0;

FPosition := 0;

end;

 

  ⑷ LoadFromStreamLoadFromFile方法

  LoadFromStream方法首先根据传入的StreamSize属性值重新分配动态内存,然后调用StreamReadBuffer方法往FMemory中复制数据,结果Stream的全部内容在内存中有了一份完整拷贝。其实现如下:

 

procedure TMemoryStream.LoadFromStream(Stream: TStream);

var

Count: Longint;

begin

Stream.Position := 0;

Count := Stream.Size;

SetSize(Count);

if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);

end; 

  LoadFromFileLoadFromStream是一对方法。LoadFromFile首先创建了一个TFileStream对象,然后调用LoadFromStream方法,将FileStream文件流中的数据写入MemoryStream中。

上一篇:开发Delphi对象式数据管理功能(三)    下一篇:开发Delphi对象式数据管理功能(一)  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-3-29
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿