2015-04-06 4 views
0

Я использую TFileStream.Read в цикле для чтения текстового файла, но я считаю, что последняя часть не считывается в буфер, хотя общее количество байтов read равно размеру файла.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 не содержит последний фрагмент файла, но 2-ой до последнего куска. Что-то не так с моим кодом?

Заранее благодарен!

+0

Фактически должна отображаться только последняя часть файла. Вы постоянно читаете в том же буфере 'buf' и переопределяете старый контент. – gabr

+0

@RawN: Итак, у меня должен быть FillChar (buf [Low (buf)], Length (buf), 0) непосредственно перед вызовом Read? –

+0

@gabr: Да, я хочу только последнюю часть файла. Я просто тестирую код на этом этапе. Но это не показывает последнюю часть ... Это показывает следующий последний кусок. –

ответ

1

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

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

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

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

+0

Я обнаружил, что «ZeroMemory (buf, bufsiz)»; перед «r: = fs.Read (buf, bufsiz)»; кажется, делает трюк! –

+0

Да, это работает для заметки, потому что это завершает нулевые байты в конце. Если вы сделали 'mystring: = stringof (buf);' вы бы получили строку с # 0 байтами в конце, которая может быть не такой, какой вы хотите. –

 Смежные вопросы

  • Нет связанных вопросов^_^