TFileStream создал файл с отсутствующими данными, записанными в него

Я написал клиент-серверный код, который перемещает файлы назад и вперед между системами через Delphi, написанный на WebService. Из-за ограничений шлюзов перед сервисом я был вынужден разбивать большие файлы на несколько сообщений. Код ниже часто работает в моем тестировании. Иногда, однако, на последнем фрагменте данных, кажется, что он не попадает в результирующий файл. У меня есть другая версия кода, где я добавлял расширенные возможности регистрации на каждом этапе, чтобы проверить текущую позицию в FileStream до и после вызова writeBuffer и получить размер промежуточного файла. Эта версия кода, кажется, работает каждый раз, что заставляет меня думать, что я могу столкнуться с какой-то проблемой синхронизации. Должен ли я делать Flush on the Stream после каждой записи или что-то подобное?

 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 ответ

Решение

Похоже, ваш вопрос заключается в том, нужно ли вам делать что-то еще, чтобы записать файл:

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

Ответ - нет. Нет необходимости что-либо сбрасывать.

Ваша проблема, возможно, связана с режимом обмена, который вы используете. Вы пошли на fmShareDenyNone, Это означает, что могут быть открыты несколько файловых дескрипторов, которые имеют доступ для записи. Это означает, что вы открыты для гонок на запись вашего файла.

Другие вопросы по тегам