delphi TMemoryStream对象用法

本文详细介绍了TMemoryStream对象的属性和方法,包括capacity属性、realloc方法、setsize方法、clear方法、loadfromstream方法及loadfromfile方法。同时深入解析了TMemoryStream的实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


======================================================
注:本文源代码点此下载
======================================================

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

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方法后,size和position属性都为0。

5. loadfromstream方法

声明:procedure loadfromstream(stream: tstream);

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

6. loadfromfile方法

声明:procedure loadfromfile(count filename: string);

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

tmemorystream对象的实现原理

tmemorystream从tcustommemorystream对象直接继承,因此可以享用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动态内存分配的核心,它的setsize、setcapacity等方法最终都是调用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。最后如果result为nil则触发内存流错的异常事件,否则返回指向分配的内存的指针。

⑵ 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,并将fsize和fposition 的值设为0。其实现如下:

procedure tmemorystream.clear;

begin

setcapacity(0);

fsize := 0;

fposition := 0;

end;

⑷ loadfromstream和loadfromfile方法

loadfromstream方法首先根据传入的stream的size属性值重新分配动态内存,然后调用stream的readbuffer方法往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;

loadfromfile与loadfromstream是一对方法。loadfromfile首先创建了一个tfilestream对象,然后调用loadfromstream方法,将filestream文件流中的数据写入memorystream中。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值