TFileStream创建了写入其中的文件丢失数据

时间:2015-03-14 05:05:36

标签: delphi tfilestream

我编写了客户端/服务器代码,通过Delphi编写的WebService在系统之间来回移动文件。由于服务前网关的限制,我被迫将大文件拆分成多个消息。下面的代码经常在我的测试中使用。然而,有时候,在最后一段数据上,它似乎没有进入生成的文件。我有另一个版本的代码,我在每一步都添加了大量的日志记录,以验证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;

1 个答案:

答案 0 :(得分:2)

您的问题似乎与您是否需要执行此操作以写入文件相关:

Stream := TFileStream.Create(...);
Try
  Stream.WriteBuffer(...);
Finally
  Stream.Free;
End;

答案是否定的。没有必要冲洗任何东西。

您的问题可能是由于您使用的共享模式。你已经去了fmShareDenyNone。这意味着可以打开具有写访问权限的多个文件句柄。这意味着您可以在文件编写方面接受比赛。