Читать строку с 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 - ключевые слова, на которые вы можете посмотреть.
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;