简体   繁体   中英

TFileStream created file missing data written to it

I've written client/server code that moves files back and forth between systems via a Delphi written WebService. Due to limitations of the gateways in front of the service, I was forced to split large files into multiple messages. The code below works often in my testing. Sometimes however, on the last piece of data, it doesn't seem to make it into the resulting file. I have another version of the code, where I've added extensive logging at every step to verify the current position in the FileStream before and after the writeBuffer calls and get the size of the intermediate file. That version of the code seems to work every time, which to me makes me think I might be hitting some kind of timing issue. Should I be doing a Flush on the Stream after each write or something similar?

 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;

Your question seems to be along the lines of whether you need to do any more than this to write to a file:

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

The answer is no. There's no need to flush anything.

Your problem is possibly due to the sharing mode that you use. You've gone for fmShareDenyNone . Which means that multiple file handles can be opened that have write access. This means that you are open to races on your file writing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM