Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];
ВнизЛог: как оптимально считать запись, состоящую из 2 строк... Найти похожие ветки
← →
Miwa (2004-02-19 01:48) [0]... при чем любой из них (первой или второй) в любом количестве записей может и не быть :о(((.
Я понимаю, что лог неправильно спроектирован, да только я даже не предполагал ТАКОГО поведения юзеров (первая строка пишется вначале процесса, вторая - в конце; за это время успевали и "породить" десяток процессов и вырубить тачку и еще черте-что...), а логов уже набралось за три месяца на сотне машин, так что менять структуру лога позновато.
Делаю так:
while not eof(f) do begin
ReadLn(f, curr1);
repeat
ReadLn(f, curr2);
if (pos("*",curr1) > 0) and (pos("*",curr2)=0)
then exit
else begin
curr1:=curr2;
continue;
end;
until false;
Кодif (pos("*",curr1) > 0) and (pos("*",curr2)=0)
объясняется тем, что символ "*" есть только в первой строке.
← →
Defunct (2004-02-19 02:25) [1]Как это:
Лог: как оптимально считать запись, состоящую из 2 строк...
Можно сопоставить с этим:
while not eof(f) do begin
ReadLn(f, curr1);
repeat
ReadLn(f, curr2);
...
???
А если там всего одна строка? Вы читаете не проверяя на Eof
PS: Вместо кода может было бы лучше привести пример лог файла, и описать проблему: что нужно с этим логом сделать.
← →
miwa (2004-02-19 02:33) [2]Пожалуйста. Пример, даже ничего подправлять не стал.
Задумка была такая:
имя файла*дата-вреия начала просмотра*длительность фильма
дата-время окончания просмотра
А вышло - вот:
\\3zork-12\video\Johnny_English.avi*04.02.2004 18:42:34*0:00:00
04.02.2004 18:42:40
\\3Zork-09\Video\Airplane2.avi*04.02.2004 18:42:42*0:00:00
04.02.2004 18:42:48
\\3Zork-11\video\American Pie.avi*04.02.2004 18:42:49*0:00:00
\\3Zork-01\Video\Американские Любимцы.AVI*04.02.2004 18:42:55*1:43:17
04.02.2004 18:42:56
04.02.2004 19:12:14
\\3Zork-01\Video\Американские Любимцы.AVI*04.02.2004 19:12:16*1:43:17
\\3Zork-23\Video\Все говорят, что я люблю тебя.AVI*04.02.2004 19:14:12*0:00:00
\\3Zork-23\Video\Все говорят, что я люблю тебя.AVI*04.02.2004 19:14:15*0:00:00
04.02.2004 19:14:15
\\3zork-25\video\признания опасного человека.avi*04.02.2004 19:14:28*1:53:37
04.02.2004 19:14:28
04.02.2004 19:15:11
\\3zork-02\video\Двухнедельное уведомление.avi*04.02.2004 19:26:57*0:00:00
04.02.2004 19:27:03
Надо записать в базу какой фильм и как задолго смотрел пользователь.
← →
Defunct (2004-02-19 03:12) [3]Да, случай действительно не из простых. Например, здесь вообще нельзя найти какой фильм когда закончили просматривать.
\\3Zork-11\video\American Pie.avi*04.02.2004 18:42:49*0:00:00
\\3Zork-01\Video\Американские Любимцы.AVI*04.02.2004 18:42:55*1:43:17
04.02.2004 18:42:56
04.02.2004 19:12:14
Ну если точность не особо важна, предлагаю такой вариант:
Читайте все строки подряд.
Размещайте строки с именем файла в один StringList, а строки с временем завершения в другой. Получится приблизительно, то что требуется.
Пропуски (там где программа была снята) можно отлавливать по дате/времени.
А на будующее все-таки было б неплохо во второй строке (там где время завершения просмотра) хранить еще один параметр: абсолютный номер первой строки в лог файле.
← →
Miwa (2004-02-19 05:33) [4]Как вам сказать - "точность не особо важна". Важна, конечно. Зачем тогда огород городить, если длительности просмотров будут "с воздуха" вытягиваться (ведь если просто по порядку в два списка скидывать - фигня выйдет когда пойдет смещение на одну запись)?
Вообще-то это случайно выпал не наилучший вариант, попадают и десятки килобайт чистого лога, так что не все так плохо. Но и нехорошо.
И еще вопросс "по ходу дела". Только что напоролся - классические AssignFile/Rewrite/Reset что - только 64К поддерживают? Тогда вообще надо переписывать все на TFileStream...
← →
miwa (2004-02-19 06:16) [5]После совета Defunct © (19.02.04 03:12) [3] и партии StarCraft ;o)) в 5 утра додумался до такого:
var s: TStringList;
i,j:integer;
begin
s:=TStringList.Create;
s.LoadFromFile(FileName);
i:=0;j:=0;
while i < s.Count do begin
while pos("*",s[i]) > 0 do inc(i);
j:=i; dec(i);
while pos("*",s[j]) = 0 do inc(j);
dec(j);
...
Вроде в s[i] - первая строка, в s[j] - вторая. Если идет несколько строк подряд, все игнорируются, остается последняя. По логам посмотрел - как правило, именно последняя является значущей.
Может, еще кто идею подбросит? Нету ведь предела совершенству.
← →
Defunct (2004-02-19 06:18) [6]> Важна, конечно. Зачем тогда огород городить, если длительности просмотров будут "с воздуха" вытягиваться (ведь если просто по порядку в два списка скидывать - фигня выйдет когда пойдет смещение на одну запись)?
Вообще-то это случайно выпал не наилучший вариант, попадают и десятки килобайт чистого лога, так что не все так плохо.
Никто ж не говорит тупо раскидывать в разные StringList, вот Вам пример, как избежать смещения на одну запись:
Читаем все строки подряд.
Попадается строка с именем файла, сразу добавляем в StringList1 ее, а в StringList2 - генерируем строку с началом просмотра. Если следующей строкой будет строка с временем завершения просмотра, заменяем ей последнюю строку в StringList2.
> И еще вопросс "по ходу дела". Только что напоролся - классические AssignFile/Rewrite/Reset что - только 64К поддерживают?
Хм.. вы привели процедуры назначение имени, открытия и создания файла. Какое отношение они имеют к размеру файла вообще? С фалом, чт/зап/позиционирование работают классические:
BlockRead(var F: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);
BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);
Seek(var f: File; Pos : LongInt );
Ограничие как видите 2Gb
← →
miwa (2004-02-19 06:25) [7]Хм.. вы привели процедуры назначение имени, открытия и создания файла. Какое отношение они имеют к размеру файла вообще?
Да я знаю. Просто, просматривая логи, которые у меня пишутся этими процедурами (тоесть, не ними, а WriteLn-ом, конечно ;о)); ними только присвоение/открытие/довбление) напоролся на одно интерессное совпадение: два из них имели до боли знакомый размер - 65536 байт. И ни один не был больше. Вот и всплыло. Раньше как-то не интересовался...
← →
Defunct (2004-02-19 06:38) [8]> (тоесть, не ними, а WriteLn-ом, конечно ;о)); ними только присвоение/открытие/довбление) напоролся на одно интерессное совпадение: два из них имели до боли знакомый размер - 65536 байт.
Может пригодится, вот приведу пример записи в Log файл строк с помощью классического BlockWrite.
Procedure TForm1.AppendLogFile;
Var F:File;
I:Integer;
S:ShortString;
Begin
{$I-}
AssignFile(F, ReportFile);
Reset(F,1);
If IOResult<>0 Then ReWrite(F,1);
If IOResult<>0 Then
Application.MessageBox(Невозможно произвести запись в файл-отчет,
"Файловая ошибка",MB_OK+16) Else
Begin
Seek(F,FileSize(F));
For I:=0 To StringList.Count-1 Do
Begin
S:= StringList[i] + #13+#10;
BlockWrite(F, S[1], Length(S));
End;
CloseFile(F);
If IOResult<>0 Then
Application.MessageBox("Неудалось закрыть файл",
"Файловая ошибка",MB_OK+16)
End;
{$I+}
End;
← →
Романов Р.В. (2004-02-19 07:53) [9]Поменяй структуру лога. Сделай конвертер и преобразуй старые логи в новый формат
← →
miwa (2004-02-19 08:24) [10]Дык, преобразовывать все равно как-то надо, правда? Вот об идеях получше той - с листбоксом (или стринглистом, если уж быть точным) я и спрашиваю.
Но все равно спасибо. Сам бы еще долго до этого доходил.
Еще?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c