Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.03;
Скачать: CL | DM;

Вниз

Лог: как оптимально считать запись, состоящую из 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.016 c
7-6260
sden
2003-12-14 17:15
2004.03.03
WinExec вызывается из сервиса


3-5940
pashaz
2004-02-06 13:53
2004.03.03
экспорт записей из одной таблицы в другую


3-5948
Zilog
2004-02-05 16:39
2004.03.03
как програмно менять порядок столбцов (Fields) в комоненте Query?


1-6061
BlackTiger
2004-02-17 18:10
2004.03.03
Как узнать ПРЕДЫДУЩИЙ активный контрол?


1-6045
Maxim_________
2004-02-19 01:45
2004.03.03
как получить из функции array of array of.......?