TFileStream.Читать не читает последнюю часть файла

Я использую TFileStream.Read в цикле для чтения текстового файла, но я обнаружил, что последняя часть не читается в буфер - хотя общее количество считываемых байтов равно размеру файла.

Это мой код:

procedure TForm1.DoImport;
var
  f: String;
  fs: TFileStream;
  r, c: Integer;
  buf: TBytes;

const
  bufsiz = 16384;
begin
  SetLength(buf, bufsiz);

  f := 'C:\Report\Claims\Claims.csv';

  fs := TFileStream.Create(f, fmOpenRead);
  try
    c := 0;
    repeat

      r := fs.Read(buf, bufsiz);

      Inc(c, r);

    until (r <> bufsiz);

    showmessage('Done. ' + IntToStr(c)); // <-- c equals to filesize !!

    Memo1.Text := StringOf(buf); // <-- but the memo does not show the last chunk of the file

  finally
    fs.Free;
  end;

end;

В конце концов, TMemo содержит не последний фрагмент файла, а второй и последний. Что-то не так с моим кодом?

Заранее спасибо!

1 ответ

Решение

Начало этого буфера содержит последний кусок вашего файла. Но после этого идет содержимое предыдущего чанка, потому что вы никогда не очищали буфер. Таким образом, вы думаете, что ваша заметка содержит предыдущий фрагмент, но это смесь обоих.

Вы можете использовать функцию копирования, чтобы просто добавить часть буфера.

Memo1.Text := StringOf(Copy(buf, 0, r)); // r is the number of bytes to copy

Лучший способ для чтения текстового файла использует TStringList или же TStringReader, Они позаботятся о кодировке файлов (Ansi, UTF8, ...). Я обычно предпочитаю TStringList, потому что у меня было слишком много проблем с некоторыми ошибками в TStringReader.

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