Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.008 c
3-5949
КомофОнСамый
2004-02-05 19:53
2004.03.03
как добавить строчку в service??


3-5944
Dummes
2004-02-05 14:53
2004.03.03
Что бы это значило?


1-6078
ddrum
2004-02-20 19:29
2004.03.03
помогите оптимизировать код


1-6065
YurikGl
2004-02-13 09:35
2004.03.03
Формирование документа Acrobat


14-6231
Undert
2004-02-10 18:48
2004.03.03
TClientSocket + POST





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский