Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чем писать лог? [D7, XP]


Страницы:   1 2 3

Б ©   (2009-10-13 17:58:00) 

Здрасти!
Работаю над логом. (Записывать много чего придёться)
Встал выбор: каким образом работать с текстовым файлом.
1 способом, через Pascal'евские - Assign, WriteLn, Reset... (Var File: Text)
2 способом, через Windows'ие - CreateFile, WriteFile... (Var File: LongWord)
Пока выбрал 1-й. (Но что-то, говорят, для логов не пойдёт)
Всё таки: какой способ лучше и быстрее?
А может есть альтернативы?


Германн   (2009-10-20 01:51:00) [1]

Начиная с "DVM ©   (18.10.09 14:24) [33]"
начался холивар, который продолжил холивар на Королевстве, и которого так жаждал автор сабжа.
Ну почему-бы автору не задать сей вопрос на www.sources.ru? Там к холиварам вроде нормально относятся.


Anatoly Podgoretsky   (2009-10-19 22:57:00) [2]

> DVM  (19.10.2009 20:17:50)  [50]

Writeln ой как не просто, начнем с того, что нет процедуры Writeln, это компьютерная магия.

Кроме того зачем сравнивать низкоуровневый вывод с высокоуровневым, когда за сценой ой как много чего справлено, избавляя от необходимости думать об преобразованиях. Можно сравнивать например с Бейсиком или некоторыми другими языками, которые имеют встроеные средства ввода/вывода.

WriteLn(F, Integer, Float, Boolean, DateTime, string) и все это одновременно в одном вызове без необходимости преобразования в текстовый формат, плюс есть и небольшие возможности форматирования вывода, что не мешает внешнему форматированию. Плюс еще и буферизация и возможность расширения.

Но есть некоторые ограничения, по режимам открытия файла, по Юникоду, ведь "функции" более 30 лет.


Leonid Troyanovsky   (2009-10-19 20:34:00) [3]


> DVM ©   (19.10.09 20:17) [50]

> Да нет там огреха.


> Очевидно, что если организовать/задействовать буферизацию
> WriteFile/TFileStream то как минимум

Дык, тут и огрех, чего у ж там далее.
Сравнивать стоит сопоставимое.

> задействовать буферизацию WriteFile/TFileStream то как минимум

Ясенное дело, что сравняются "как минимум", бо выше - overhead.

--
Regards, LVT.


DVM   (2009-10-19 20:17:00) [4]


> Leonid Troyanovsky ©   (19.10.09 18:58) [49]


> а мы постараемся найти огрех.

Да нет там огреха. Понятно, что я сравнивал "просто Writeln" с "просто WriteFile" и TFileStream.Write(). Только вот "просто Writeln"  оказался "просто буферизованный Writeln".

Большинство ведь и не догадываются о том, что Writeln использует хитрую буферизацию и внутренности Writeln как правило мало кем изучаются и Writeln рассматривается как нечто совсем простое как 2 копейки. Ан нет оказывается, Writeln не так прост. Я вот сам заблуждался.

Очевидно, что если организовать/задействовать буферизацию WriteFile/TFileStream то как минимум они сравняются.


Leonid Troyanovsky   (2009-10-19 18:58:00) [5]


> DVM ©   (19.10.09 00:47) [47]

> > У тебя тесты какие-то неправильные.

> Может поделишься правильными?

Ну, ты ж сам все правильно объяснил.
Внизу лежит WriteFile, сверху - overhead.
Там же еще парсинг строк и т.п.

Сравнивать можно, скажем, WriteFile vs memory mapped file,
хотя, наверное, и это мну не очень интересно.

Проще, наверное, если б ты показал сравнения
(у тебя, IMHO, д.б. где-то под рукой),
а мы постараемся найти огрех.

--
Regards, LVT.


sniknik   (2009-10-19 01:08:00) [6]

> Может поделишься правильными?
лучше "правильным" компьютером с новыми дисками которым программная буферизация только мешает... (адрес для "дележки" в личку ;о) )


DVM   (2009-10-19 00:47:00) [7]


> Leonid Troyanovsky ©   (18.10.09 23:46) [46]


> У тебя тесты какие-то неправильные.

Может поделишься правильными? И мы поучимся.


Leonid Troyanovsky   (2009-10-18 23:46:00) [8]


> DVM ©   (18.10.09 16:06) [39]

> Writeln почти в 2 раза обгоняет Windows.WriteFile и соответственно
> TFileStream.

У тебя тесты какие-то неправильные.

--
Regards, LVT.


Игорь Шевченко   (2009-10-18 21:19:00) [9]

DVM ©   (18.10.09 20:42) [44]

Как ты понимаешь - кому что надо, кому надо подробный лог для диагностики (а для чего еще лог нужен?), кому надо быстро. Для "быстрого" протоколирования мы использовали отдельный процесс, которому посылали сообщения о необходимости занесения в протокол тех или иных данных, натурально, у этого процесса был достаточный буфер, чтобы он не захлебывался при приеме сообщений с достаточно интенсивной скоростью, разумеется, было управление файлами, чтобы текущий протокол по достижении нужного размера/количества записей отключался и сбрасывался в базу данных/архив, а запись при этом велась в другой файл, ну и так далее.

Только сложно это - мы использовали для протоколирования работы нескольких связанных процессов, Event log нам не понравился, уж больно неудобно делать его пост-обработку.


DVM   (2009-10-18 20:42:00) [10]


> Игорь Шевченко ©   (18.10.09 19:00) [42]


> Для лога, я считаю, гораздо удобнее в ряде случаев использовать
> не буферизованный ввод/вывод, а закрытие файла после каждой
> записи

Только у этого способа есть один недостаток - уж слишком сильно замедляет программу при интенсивном логгировании.


Eraser   (2009-10-18 20:04:00) [11]

для отладки использую
unit ROMLog;

interface

uses
 Windows, SysUtils;

function AppendLog(const AMsg: string): Boolean;

var
 _csROMLog: TRTLCriticalSection;

implementation

function AppendLog(const AMsg: string): Boolean;
var
 fText: TextFile;
 sFileName, sText: string;
begin
 Result := False;
 try
   sFileName := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
   if not DirectoryExists(sFileName + 'Logs') then
     MkDir(sFileName + 'Logs');
   sFileName := sFileName + 'Logs\' + FormatDateTime('yyyy_mm', Now) +
     '_rom_log.txt';
 except
   Exit;
 end;

 EnterCriticalSection(_csROMLog);
 try
   AssignFile(fText, sFileName);
   if FileExists(sFileName) then
     Append(fText)
   else
     Rewrite(fText);
   try
     sText := FormatDateTime('dd-mm-yyyy_hh:nn:ss', Now) +
       '#T:' + AMsg;
     Writeln(fText, sText);
   finally
     CloseFile(fText);
   end;

   Result := True;
 finally
   LeaveCriticalSection(_csROMLog);
 end;
end;

initialization
 InitializeCriticalSection(_csROMLog);

finalization
 DeleteCriticalSection(_csROMLog);

end.


если лог нужен для функционала, то лучше использовать другой подход.


Игорь Шевченко   (2009-10-18 19:00:00) [12]

Для лога, я считаю, гораздо удобнее в ряде случаев использовать не буферизованный ввод/вывод, а закрытие файла после каждой записи. В этом случае удобно а) смотреть лог работающей программы б) в случае ошибки в программе все данные лога будут на диске (а не в текстовом буфере), что в ряде случаев упрощает диагностику.

Кстати, конструкция

AssignFile(F, 'foo');
if FileExists('foo') then
 Append(F)
else
 Rewrite(F);

Лмается на файлах больше двух гигагбайт. Но я не пишу логи в несколько гигабайт - уж больно с ними потом неудобно работать :)


DVM   (2009-10-18 16:33:00) [13]


> Sapersky   (18.10.09 16:20) [40]
>
> WriteLn буферизованный.

Да, так и есть. Если писать довольно большими кусками он начинает чуть отставать от Windows.WriteFile


Sapersky   (2009-10-18 16:20:00) [14]

WriteLn буферизованный. Если ещё буфер задать 2-4 кб вместо стандартных 128 байт (SetTextBuf), будет ещё быстрее.
Я в той ветке на Королевстве выкладывал результат сравнения буферизованного (хотя и не конкретно WriteLn) и небуферизованного методов - разница в 3.5 раза.


DVM   (2009-10-18 16:06:00) [15]


>
> > Вряд ли. Где тесты на сравнение и результаты?
>
> Без проблем щас организуем.

Провел сравнительное тестирование TextFile/Writeln , TFileStream и Windows.WriteFile.

Результаты оказались довольно неожиданными для меня.
Writeln почти в 2 раза обгоняет Windows.WriteFile и соответственно TFileStream.
Самое удивительное, что  Writeln сводится к той же Windows.WriteFile

Так что насчет скорости я был не прав.


DVM   (2009-10-18 15:25:00) [16]


> Выдает:
>
> ---------------------------
> Project1
> ---------------------------
> Error: 105:I/O error 105(Операция успешно завершена/Этот
> семафор более не принадлежит использовавшему его процессу)
> ---------------------------
> OK  
> ---------------------------
>
> Ерунда какая то.

Хотя нет, извиняюсь, не заметил что в твоем коде Reset(f); а не Rewrite;


DVM   (2009-10-18 15:14:00) [17]


> qwer_qwer   (18.10.09 14:53) [34]


> Если это не преимущество и недостаток, тогда зачем это упоминать?
>  Для красного словца?

Я не упоминал.


> Пожалуйста. В чём проблема-то? В неумении?

Да насчет отсутствующего диска я  погорячился, но хорошо, вот другой пример, файл c:\1.txt имеет атрибут только чтение (или нет доступа со стороны файловой системы)
Твой код:

]
procedure TForm1.btn1Click(Sender: TObject);
var
f: TextFile;
begin
try
AssignFile(f,'c:\1.txt');
Reset(f);
write(f, 'test');
CloseFIle(f);
except
  on E: EInOutError do
    ShowMessage('Error: '+IntToStr(E.ErrorCode)+':'+E.Message+
      '('+SysErrorMessage(GetLastError)+'/'+SysErrorMessage(E.ErrorCode)+')');
end;

end;



Выдает:

---------------------------
Project1
---------------------------
Error: 105:I/O error 105(Операция успешно завершена/Этот семафор более не принадлежит использовавшему его процессу)
---------------------------
OK  
---------------------------

Ерунда какая то.

Правильный код на TFileStream:

procedure TForm1.btn2Click(Sender: TObject);
var
 Stream: TFileStream;
 s: string;
begin
 s := 'test';
 Stream := TFileStream.Create('c:\1.txt', fmOpenWrite);
 try
   Stream.Write(s[1], Length(s) * SizeOf(Char));
 finally
   Stream.Free;
 end;
end;


выдает

---------------------------
Project1
---------------------------
Cannot open file "c:\1.txt". Отказано в доступе.
---------------------------
ОК  
---------------------------


> Вряд ли. Где тесты на сравнение и результаты?

Без проблем щас организуем.


Плохиш   (2009-10-18 15:13:00) [18]


> qwer_qwer   (18.10.09 14:53) [34]

> Вообще-то на этих форумах технические специалисты, а не
> гуманитарии с любовью к красивым словам

Экма :-) "наивный чукотский мальчик" :-))


qwer_qwer   (2009-10-18 14:55:00) [19]

Особенно красиво звучит ничем не обоснованное -

> можно продолжать бесконечно и во всех случаях толковой информации
> о том что же произошло от этих функций не получишь.


qwer_qwer   (2009-10-18 14:53:00) [20]


> Вот именно, это даже не преимущество. Так что преимуществ
> у паскалевских методов работы с файлами нет вообще. Анахронизм
> это.


Если это не преимущество и недостаток, тогда зачем это упоминать? Для красного словца? Вообще-то на этих форумах технические специалисты, а не гуманитарии с любовью к красивым словам.


> Ну обработай мне исключение, которое возникает при доступе
> паскалевской функции к дисководу в котором нет диска. Или
> когда отсутствуют права на доступ к файлу, или ... эти или
> можно продолжать бесконечно и во всех случаях толковой информации
> о том что же произошло от этих функций не получишь. Хошь
> обрбатывай, хошь не обрабатывай.


Пожалуйста. В чём проблема-то? В неумении?

procedure TForm1.Button1Click(Sender: TObject);
var
 f: TextFile;
begin
 try
 AssignFile(f,'a:\1.txt');
 Reset(f);
 CloseFIle(f);
 except
   on E: EInOutError do
     ShowMessage('Îøèáêà '+IntToStr(E.ErrorCode)+':'+E.Message+
       '('+SysErrorMessage(GetLastError)+'/'+SysErrorMessage(E.ErrorCode)+')');
 end;

end;



> Попробуй писать очень интенсивно и много - разница налицо.


Вряд ли. Где тесты на сравнение и результаты?


> Задачи никакой не ставилось. А потокобезопасный лог - сплошь
> и рядом треуется.


Вот когда он потребуется, тогда и потребуется отдельное обсуждение для конкретной задачи.


> Такого, какого позволяет файловая система, не меньше.


А если точнее? В Мб,Гб, Тб?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо