Delphi TFileStream创建的文件缺少写入的数据
我已经编写了客户机/服务器代码,通过Delphi编写的Web服务在系统之间来回移动文件。由于服务前网关的限制,我被迫将大文件拆分为多条消息。下面的代码经常在我的测试中使用。然而,有时,在最后一段数据上,它似乎没有进入结果文件。我有另一个版本的代码,我在每一步都添加了大量日志记录,以在writeBuffer调用前后验证FileStream中的当前位置,并获取中间文件的大小。这个版本的代码似乎每次都能工作,这让我觉得我可能遇到了某种时间问题。我应该在每次写入后对流进行刷新还是类似的操作Delphi TFileStream创建的文件缺少写入的数据,delphi,tfilestream,Delphi,Tfilestream,我已经编写了客户机/服务器代码,通过Delphi编写的Web服务在系统之间来回移动文件。由于服务前网关的限制,我被迫将大文件拆分为多条消息。下面的代码经常在我的测试中使用。然而,有时,在最后一段数据上,它似乎没有进入结果文件。我有另一个版本的代码,我在每一步都添加了大量日志记录,以在writeBuffer调用前后验证FileStream中的当前位置,并获取中间文件的大小。这个版本的代码似乎每次都能工作,这让我觉得我可能遇到了某种时间问题。我应该在每次写入后对流进行刷新还是类似的操作 respo
responseObj := DocSvc.getDocument(GetFileInHeader, GetFileIn);
while processingGetFile do
begin
chunkID := StrToInt(responseObj.ValidationResults[0].ValidationResultId);
if chunkID = -3 then
begin
processingGetFile := false;
break;
end;
if chunkID = -2 then
begin
if responseObj.opsResponseobj.status then
begin
if responseObj.opsResponseObj.document <> 'NONEWFILE' then
begin
if FileExists2(DesintationFilePath) then
DeleteFile(DesintationFilePath);
Zipfile := TFileStream.Create(DesintationFilePath,FmOpenReadWrite or FmShareDenyNone or fmCreate);
DecodedZipfile := DecodeString(responseObj.opsResponseobj.document);
Zipfile.WriteBuffer(Pointer(DecodedZipfile)^, length(DecodedZipfile));
iniTransmit.WriteString(‘DocumentSection’,string(FileID), responseObj.ValidationResults[0].ReasonCode);
FreeAndNil(Zipfile);
end;
result := true;
processingGetFile := false;
end
else
begin
//Log failure
end;
end
else if chunkID = -1 then
begin
Zipfile.Position := getFileSize(DesintationFilePath);
DecodedZipfile := DecodeString(responseObj.opsResponseObj.document);
Zipfile.WriteBuffer(Pointer(DecodedZipfile)^, Length(DecodedZipfile));
iniTransmit.WriteString(‘DocumentSection’,string(FileID), responseObj.ValidationResults[0].ReasonCode);
result := true;
processingGetFile := false;
end
else // in the middle of receiving pieces of a big file. Save off what we have, ask for more.
begin
if chunkID = 1 then
begin
if FileExists2(DesintationFilePath) then
DeleteFile(DesintationFilePath);
Zipfile := TFileStream.Create(DesintationFilePath,FmOpenReadWrite or FmShareDenyNone or fmCreate);
end;
Zipfile.Position := getFileSize(DesintationFilePath);
DecodedZipfile := DecodeString(responseObj.opsResponseObj.document);
Zipfile.WriteBuffer(Pointer(DecodedZipfile)^, Length(DecodedZipfile));
GetFileInHeader.messageFlowSequence := chunkID;
responseObj := DocSvc.getDocument(GetFileInHeader, GetFileIn);
end;
end;
function getFileSize(path: string): integer;
var
info : TWin32FileAttributeData;
begin
result := -1;
if not GetFileAttributesex(Pchar(path), GetFileExInfoStandard, @info) then
exit;
result := (info.nFileSizeLow or (info.nFileSizeHigh shl 32));
end;
responseObj:=DocSvc.getDocument(GetFileInHeader,GetFileIn);
在处理GetFile时,请执行以下操作:
开始
chunkID:=stroint(responseObj.ValidationResults[0].ValidationResultId);
如果chunkID=-3,则
开始
processingGetFile:=false;
中断;
结束;
如果chunkID=-2,则
开始
如果responseObj.opsResponseobj.status,则
开始
如果responseObj.opsResponseObj.document“NONEWFILE”,则
开始
如果文件存在2(DestinationFilePath),则
删除文件(DestinationFilePath);
Zipfile:=TFileStream.Create(DestinationFilePath、FmOpenReadWrite或FMSharedInOne或fmCreate);
DecodedZipfile:=DecodeString(responseObj.opsResponseobj.document);
WriteBuffer(指针(DecodedZipfile)^,长度(DecodedZipfile));
InitTransmit.WriteString('DocumentSection',字符串(FileID),responseObj.ValidationResults[0].ReasonCode);
FreeAndNil(Zipfile);
结束;
结果:=真;
processingGetFile:=false;
结束
否则
开始
//日志失败
结束;
结束
否则,如果chunkID=-1,则
开始
Zipfile.Position:=getFileSize(DestinationFilePath);
DecodedZipfile:=DecodeString(responseObj.opsResponseObj.document);
WriteBuffer(指针(DecodedZipfile)^,长度(DecodedZipfile));
InitTransmit.WriteString('DocumentSection',字符串(FileID),responseObj.ValidationResults[0].ReasonCode);
结果:=真;
processingGetFile:=false;
结束
另外,/在一个大文件的接收部分中间。省掉我们所拥有的,要求更多。
开始
如果chunkID=1,则
开始
如果文件存在2(DestinationFilePath),则
删除文件(DestinationFilePath);
Zipfile:=TFileStream.Create(DestinationFilePath、FmOpenReadWrite或FMSharedInOne或fmCreate);
结束;
Zipfile.Position:=getFileSize(DestinationFilePath);
DecodedZipfile:=DecodeString(responseObj.opsResponseObj.document);
WriteBuffer(指针(DecodedZipfile)^,长度(DecodedZipfile));
GetFileInHeader.messageFlowSequence:=chunkID;
responseObj:=DocSvc.getDocument(GetFileInHeader,GetFileIn);
结束;
结束;
函数getFileSize(路径:string):整数;
变量
信息:TWin32FileAttributeData;
开始
结果:=-1;
如果不是GetFileAttributesex(Pchar(路径)、GetFileExInfo标准、@info),则
退出;
结果:=(info.nFileSizeLow或(info.nFileSizeHigh shl 32));
终止
您的问题似乎是您是否需要执行更多操作才能写入文件:
Stream := TFileStream.Create(...);
Try
Stream.WriteBuffer(...);
Finally
Stream.Free;
End;
答案是没有。没有必要冲洗任何东西
您的问题可能是由于您使用的共享模式造成的。您选择了
fmsharedynone
。这意味着可以打开具有写访问权限的多个文件句柄。这意味着你在写文件时可以参加比赛 由于代码重复,阅读起来很困难。使用变量以避免重复使用相同的字符串。将文件写入代码拆分为单独的方法会有所帮助。您需要使用try/finallyinfo.nFileSizeHigh shl 32=info.nFileSizeHigh
。在应用shl之前,您需要强制转换到Int64。这只是整个函数的一个摘录,它确实位于try/except块中用于错误处理,而try/finally块用于释放资源。当出现并非所有数据都进入文件的问题时,不会出现异常。代码显然已丢失。不管怎么说,复制品让人难以阅读。你在乞求错误。