delphi6中用TFileStream进行文件读写遇到的诡异问题

探讨使用Delphi TFileStream写入分块字节流时遇到的问题及解决方案,特别是对比fmCreate与fmOpenWrite的区别。

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

从服务器下载文件,由于是通过WEB SERVICE调用,对于文件采用分块字节流从WEB SERVICE取出(文件数据块返回的是动态字节数组TByteDynArray),并写入到本地文件中,代码片断:
procedure WriteStreamToFile(fileName: String; offset : Integer; bt : TByteDynArray);
var fs : TFileStream;
begin
  fs :
= TFileStream.Create(fileName, fmCreate);
  fs.Seek(offset, soFromBeginning);
  fs.Write(Pointer(bt)
^,Length(bt));
  fs.Free;
end;

最后生成的文件大小和源文件的大小相同,但就是打开文件出错(测试文件是zip文件,解压时出错)。难道是往文件中写入字节流时,字节流的指针位置不对?调试,也没发现从web service获取的字节数组有数据错乱或丢失的情况。于是又用ultra edit对源文件和错误文件进行比较,发现错误文件的末尾部分,好像是最后一次写入的字节数组是对的,其他部分的字节十六进制都是00。这到底是怎么回事啊??是不是在Create方法中传入的参数fmCreate有问题呢,顾名思义,每次以创建的方式打开文件,是不是就把之前的文件内容都清掉了。查看delphi帮助是这么说的:

fmCreate Create a file with the given name. If a file with the given name exists, open the file in write mode.

写的很清楚,对于文件已经存在的,则打开并采用写模式。但是根本就没说会将之前的文件内容清掉啊!浪费了我大半天的时间也没有找到原因。最后无意间发现,当本地磁盘中已有此文件,但是Create的方式为fmOpenWrite时,问题就解决了,前提是同名的文件必须存在,delphi帮助是这样解释fmOpenWrite的:

fmOpenWrite Open the file for writing only. Writing to the file completely replaces the current contents.

以只写的方式打开文件,并将数据完全替换掉当前的内容。也就是说在当前文件流指针所在position开始,将传入的数据替换掉之前的数据,替换的数据长度是由传入的数据长度而定。所以当本地磁盘有相同文件名的文件,但大小大于源文件时,剩余的数据是不会被替换掉的,也就是写入数据完成后的文件大小不会改变。

最后在写入数据之前又加上了几句代码,才搞定此问题:

但是上面的解决办法让心里总觉得别扭,希望还有更好的办法。

......
// 先删除已存在的本地文件,再创建一个同名的空文件
DeleteFile(fileName);
fileHandle :
= FileCreate(fileName);
FileClose(fileHandle);
.....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值