![]() |
![]() ![]() ![]() ![]() |
|
Прочитать строку под нужным номером из текстового файлаDelphi , Файловая система , ФайлыПрочитать строку под нужным номером из текстового файла
Оформил: DeeCo
{
Abstract:
Im trying to write a function that, given a FileName and a line number
returns the entire line in a string.
}
{
The following technique is useful for high-speed processing.
The sample program file, save it with a .pas or .dpr filename and compile it.
}
{$APPTYPE CONSOLE}
uses SysUtils, Classes;
function GrabLine(const AFileName: string; ALine: Integer): string;
var
fs: TFileStream;
buf: packed array[0..4095] of Char;
bufRead: Integer;
bufPos: PChar;
lineStart: PChar;
tmp: string;
begin
fs := TFileStream.Create(AFileName, fmOpenRead);
try
Dec(ALine);
bufRead := 0;
bufPos := nil;
{ read the first line specially }
if ALine = 0 then
begin
bufRead := fs.Read(buf, SizeOf(buf));
if bufRead = 0 then
raise Exception.Create('Line not found');
bufPos := buf;
end else
while ALine > 0 do
begin
{ read in a buffer }
bufRead := fs.Read(buf, SizeOf(buf));
if bufRead = 0 then
raise Exception.Create('Line not found');
bufPos := buf;
while (bufRead > 0) and (ALine > 0) do
begin
if bufPos^ = #10 then
Dec(ALine);
Inc(bufPos);
Dec(bufRead);
end;
end;
{ Found the beginning of the line at bufPos... scan for end.
2 cases:
1) we'll find it before the end of this buffer
2) it'll go beyond this buffer and into n more buffers }
lineStart := bufPos;
while (bufRead > 0) and (bufPos^ <> #10) do
begin
Inc(bufPos);
Dec(bufRead);
end;
{ if bufRead is positive, we'll have found the end and we can leave. }
SetString(Result, lineStart, bufPos - lineStart);
{ determine if there are more buffers to process }
while bufRead = 0 do
begin
bufRead := fs.Read(buf, SizeOf(buf));
lineStart := buf;
bufPos := buf;
while (bufRead > 0) and (bufPos^ <> #10) do
begin
Inc(bufPos);
Dec(bufRead);
end;
SetString(tmp, lineStart, bufPos - lineStart);
Result := Result + tmp;
end;
finally
fs.Free;
end;
end;
function GrabLine2(const s: string; ALine: Integer): string;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.LoadFromFile(s);
Result := sl[ALine - 1]; // index off by one
finally
sl.Free;
end;
end;
begin
Writeln(GrabLine(ParamStr(1), StrToInt(ParamStr(2))));
Writeln(GrabLine2(ParamStr(1), StrToInt(ParamStr(2))));
end.
{
Call it like 'getline testfile.txt 20000', depending on what you call the
.pas (or .dpr) file. For large (i.e. tens of megabytes) files, the (rather
complex) scanning function easily beats the memory expensive StringList
version.
-- Barry
}
Программа на Delphi, которая читает текстовый файл и возвращает строку на указанной позиции. Программа имеет два функциона:
Программа также включает в себя некоторые примеры кода в конце, которые демонстрируют, как вызывать эти функции из командной строки. Вот пример, как можно прочитать конкретную строку из текстового файла: Вы можете запустить эту программу из командной строки следующим образом: Это будет печатать 20000-ю строку Прочитать строку под нужным номером из текстового файла - функция GrabLine позволяет выполнить это с помощью оперативной памяти, а функция GrabLine2 использует TStringList для чтения текстового файла. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 | ||||