Delphi TFileStream创建的文件缺少写入的数据

Delphi TFileStream创建的文件缺少写入的数据,delphi,tfilestream,Delphi,Tfilestream,我已经编写了客户机/服务器代码,通过Delphi编写的Web服务在系统之间来回移动文件。由于服务前网关的限制,我被迫将大文件拆分为多条消息。下面的代码经常在我的测试中使用。然而,有时,在最后一段数据上,它似乎没有进入结果文件。我有另一个版本的代码,我在每一步都添加了大量日志记录,以在writeBuffer调用前后验证FileStream中的当前位置,并获取中间文件的大小。这个版本的代码似乎每次都能工作,这让我觉得我可能遇到了某种时间问题。我应该在每次写入后对流进行刷新还是类似的操作  respo

我已经编写了客户机/服务器代码,通过Delphi编写的Web服务在系统之间来回移动文件。由于服务前网关的限制,我被迫将大文件拆分为多条消息。下面的代码经常在我的测试中使用。然而,有时,在最后一段数据上,它似乎没有进入结果文件。我有另一个版本的代码,我在每一步都添加了大量日志记录,以在writeBuffer调用前后验证FileStream中的当前位置,并获取中间文件的大小。这个版本的代码似乎每次都能工作,这让我觉得我可能遇到了某种时间问题。我应该在每次写入后对流进行刷新还是类似的操作

 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/finally
info.nFileSizeHigh shl 32=info.nFileSizeHigh
。在应用shl之前,您需要强制转换到Int64。这只是整个函数的一个摘录,它确实位于try/except块中用于错误处理,而try/finally块用于释放资源。当出现并非所有数据都进入文件的问题时,不会出现异常。代码显然已丢失。不管怎么说,复制品让人难以阅读。你在乞求错误。