Читать строку с TFileStream Delphi

Как мне прочитать файл, используя определенные строки TFileStream. Я читаю строки, которые имеют миллионы файлов. Поэтому я хочу играть в памяти, которую я буду использовать только

Пример:

Line 1: 00 00 00 00 00 00 00 00
Line 2: 00 00 00 00 00 00 00 00
Line 3: 00 00 00 00 00 00 00 00
Line 4: 00 00 00 00 00 00 00 00
Line 5: 00 00 00 00 00 00 00 00

Я читаю строки от 2 до 4

Я использовал функцию TextFile, но она кажется медленной. Только что нашел функцию, которая читает последнюю строку в TFileStream.

3 ответа

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

FileStream := TFileStream.Create( 'MyBigTextFile.txt', fmOpenRead)

TFileStream не является объектом с подсчетом ссылок, поэтому убедитесь, что выпустите его, когда закончите, вот так...

FileStream.Free

С этого момента я буду предполагать, что кодировка символов вашего файла - UTF-8 и что конец строки - в стиле MS. Если нет, пожалуйста, внесите соответствующие изменения или обновите свой вопрос.

Вы можете прочитать одну единицу кода символа UTF-8 (не то же самое, что чтение одного символа) следующим образом:

var ch: ansichar;
FileStream.ReadBuffer( ch, 1);

Вы можете прочитать строку текста так...

function ReadLine( var Stream: TStream; var Line: string): boolean;
var
  RawLine: UTF8String;
  ch: AnsiChar;
begin
result := False;
ch := #0;
while (Stream.Read( ch, 1) = 1) and (ch <> #13) do
  begin
  result := True;
  RawLine := RawLine + ch
  end;
Line := RawLine;
if ch = #13 then
  begin
  result := True;
  if (Stream.Read( ch, 1) = 1) and (ch <> #10) then
    Stream.Seek(-1, soCurrent) // unread it if not LF character.
  end
end;

Чтобы прочитать строки 2, 3 и 4, предполагая, что позиция в 0 ...

ReadLine( Stream, Line1);
ReadLine( Stream, Line2);
ReadLine( Stream, Line3);
ReadLine( Stream, Line4);

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

Blockread, BlockWrite, Seek - ключевые слова, на которые вы можете посмотреть.

Пример страницы для BlockRead

Пример страницы для поиска

Code Sean предлагает медленно из-за TFileStream.Read, как объяснил Дэвид. Но если вы используете TMemoryStream вместо TFileStream, медленный Stream.Read не так важен. В таком случае строковые операции занимают большую часть времени.

Если вы немного измените код, скорость будет примерно в 2 раза выше:

function ReadLine(Stream: TStream; var Line: string): boolean;
var
  ch: AnsiChar;
  StartPos, LineLen: integer;
begin
  result := False;
  StartPos := Stream.Position;
  ch := #0;
  while (Stream.Read( ch, 1) = 1) and (ch <> #13) do;
  LineLen := Stream.Position - StartPos;
  Stream.Position := StartPos;
  SetString(Line, NIL, LineLen);
  Stream.ReadBuffer(Line[1], LineLen);
  if ch = #13 then
    begin
    result := True;
    if (Stream.Read( ch, 1) = 1) and (ch <> #10) then
      Stream.Seek(-1, soCurrent) // unread it if not LF character.
    end
end;
Другие вопросы по тегам