Форум: "Основная";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
ВнизТекстовый файл Найти похожие ветки
← →
Separator (2003-01-08 07:06) [0]Как можно считать последние 50 строчек текстового файла?
← →
BoxTer (2003-01-08 07:24) [1]var N,i,k:integer;
s:string;
f:textfile;
begin
assignfile(f,"111.txt");
reset(f);
while not EoF(f) do begin
writeln(f,s);
n:=n+1;
end;
//n-Всего строк
k:=0;
while not EoF(f) do begin
writeln(f,s);
k:=k+1;
if k>=n-50 then //еси строчка из последних 50
Memo1.Lines.Add(s); //в Мемо ее!
end;
closefile(f);
извиняйте если шо... на скорую руку
← →
Дмитрий К.К. (2003-01-08 07:26) [2]Если текстовый файл не громадных размеров, то грузить его в StringList.
← →
Separator (2003-01-08 07:29) [3]Файл может быть и громадного размера
BoxTer © (08.01.03 07:24 ничего, но два раза перебрать весь файл, это конечно круто, но очень не эффективно
← →
Maksss (2003-01-08 07:37) [4]f:= TFileStream.Create("youfile.qwe",fmShareDenyNone);
f.position(f.size-50);
f.read(s,50);
f.free;
помоему так
← →
VAleksey (2003-01-08 07:43) [5]
> Separator © (08.01.03 07:29)
а по большому счету больше никак :)))
← →
Alx2 (2003-01-08 07:45) [6]>Separator © (08.01.03 07:29)
ИМХО задача с неоднозначным решением, посему можно попробовать последовательные приближения:
С помощью seek едем к почти концу файла и читаем оттуда, например, 4Kb. Если в этом прочитанном куске >50 строк, то задача выполнена (кол-во строк можно считать по наличию знаков #13, #10 (и еще учесть, что последняя строчка может не содержать знаков конца строки)). Иначе - читаем еще предыдущих 4Kb.
Конечно, надо предусмотреть вариант, если прочитанный кусок начинается не с начала строки. Для этого и написал условие >50 строк. Ну и проверка на достижение начала файла :)
← →
Separator (2003-01-08 09:27) [7]Мне нужно вообще-то вести лог файл, ночтоб при запуске проги считывались последние 50 записей, я уже думаю использовать типизированный файл, но еще пока экспериминтирую
← →
Anatoly Podgoretsky (2003-01-08 09:36) [8]Separator © (08.01.03 09:27)
Что бы использовать типизированный файл, надо иметь строки фиксированной длины
← →
Maksss (2003-01-08 09:39) [9]в твоём случае удобней будет пользоваться командой insert(0,string) а не add . куда ты там добовляеш тогда последние 50 строк будут первыми
← →
Separator (2003-01-08 12:01) [10]
> Maksss (08.01.03 09:39)
Это я уже понял, но в файле уже сейчас намного больше 50-ти строк
> Anatoly Podgoretsky © (08.01.03 09:36)
> Что бы использовать типизированный файл, надо иметь строки
> фиксированной длины
Это я знаю, но пока путь будет так, а скорей всего я сделаю как посоветовал Alx2 © (08.01.03 07:45). Я сейчас пока экспереминтирую
← →
Anatoly Podgoretsky (2003-01-08 12:06) [11]А тебе именно 50 строк или приблизительно?
← →
Separator (2003-01-08 12:12) [12]Приблизительно, вообще это число я взял просто наугад, может быть луюбое. Просто я в программе отображаю только 50 строк, но это может быть изменено. Скажим так мне надо вытащить n-ное количество строк начиная с конца файла
← →
Separator (2003-01-08 12:28) [13]
procedure TForm1.AddLog(LogString: String);
var
F: TFileStream;
PStr: PChar;
LengthLogString: integer;
begin
LengthLogString:= Length(LogString) + 2;
LogString:= LogString + #13#10;
PStr:= StrAlloc(LengthLogString + 1);
StrPCopy(PStr, LogString);
if FileExists("LogFile.Log") then
F:= TFileStream.Create("LogFile.Log", fmOpenWrite)
else
F:= TFileStream.Create("LogFile.Log", fmCreate);
F.Position:= F.Size;
F.Write(PStr, LengthLogString);
StrDispose(PStr);
F.Free;
end;
Этот код добавляет строку в файл. У меня возник вопрос почему Position и Size всегда равны 0?
← →
Separator (2003-01-08 14:43) [14]На мой последний вопрсо не обращайте внимание, просто я не посмотрел, что они int64.
Задачу я все-таки решил:
procedure TForm1.GetLog(Count: integer; Strings: TStrings);
var
F: TFileStream;
PStr: PChar;
St: string;
i, LenBlock, LenFirstString: integer;
TempStrings: TStringList;
begin
if FileExists("LogFile.Log") then
begin
LenBlock:= 4000;
TempStrings:= TStringList.Create;
F:= TFileStream.Create("LogFile.Log", fmOpenRead);
F.Position:= F.Size;
LenFirstString:= 0;
PStr:= StrAlloc(LenBlock);
repeat
if F.Position - LenBlock < 0 then
begin
LenBlock:= F.Position;
StrDispose(PStr);
PStr:= StrAlloc(LenBlock);
end;
F.Position:= F.Position - LenBlock;
F.Read(PStr^, LenBlock);
St:= PStr;
SetLength(St, LenBlock);
TempStrings.Text:= St;
F.Position:= F.Position - LenBlock;
if F.Position <> 0 then
begin
LenFirstString:= Length(TempStrings.Strings[0]);
TempStrings.Delete(0)
end
else
LenFirstString:= 0;
F.Position:= F.Position + LenFirstString;
for i:= TempStrings.Count - 1 downto 0 do
begin
Strings.Add(TempStrings.Strings[i]);
if Strings.Count = Count then
begin
F.Free;
TempStrings.Free;
StrDispose(PStr);
exit
end
end;
until F.Position = 0;
StrDispose(PStr);
F.Free;
TempStrings.Free
end
end;
Выложил на всякий случай, может кто найдет что оптимизировать
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c