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

Вниз

Реализация лог-файла.   Найти похожие ветки 

 
Игорь Шевченко ©   (2005-12-09 16:14) [40]

Владислав ©   (09.12.05 14:25) [33]


> function CloseAndNilHandle(var AHandle: THandle): Boolean;
>
> var
>  TempHandle: THandle;
> begin
>  TempHandle := AHandle;
>  Result := TempHandle = 0;
>  if not Result then
>  begin
>    AHandle := 0;
>    Result := CloseHandle(TempHandle);
>  end;
> end;


Народу непонятно, зачем нужна временная переменная.


>  FWorkEvent := CreateEvent(nil, False, False, nil);
>  if FWorkEvent = 0 then
>    Terminate;


А почему объект не создался, никого нафиг не интересует, верно ?


> destructor TLogFileThread.Destroy;
> begin
>  CloseAndNilHandle(FWorkEvent);
>  inherited;
> end;


Нафига, собственно, обнулять значение поля FWorkEvent в деструкторе ? Отмазки про наследников не катят - поле приватное :)


>   if FWorkEvent <> 0 then
>      SetEvent(FWorkEvent);


А эта проверка зачем ?
В конструкторе сделан страшный Terminate, если FWorkEvent = 0, поток, насколько я понимаю, выполняться не будет, Wait тоже не выполнится и SetEvent будет сделан впустую


 
Владислав ©   (2005-12-09 16:19) [41]


> Игорь Шевченко ©   (09.12.05 16:14) [40]


Спасибо! Ушел думать...

:)


 
Владислав ©   (2005-12-09 16:35) [42]


> Народу непонятно, зачем нужна временная переменная.


Наверное, чтобы в случае исключения все же обнулить хендл? Даже не знаю :) Типа перестраховался :)


> А почему объект не создался, никого нафиг не интересует,
>  верно ?
> ...
> Нафига, собственно, обнулять значение поля FWorkEvent в
> деструкторе ? Отмазки про наследников не катят - поле приватное
> :)


Еще как интересует!
Мы пойдем другим путем :)

constructor TLogFileThread.Create(ALogFile: TLogFile);
begin
 FLogFile := ALogFile;
 FWorkEvent := CreateEvent(nil, False, False, nil);
 if FWorkEvent = 0 then
   RaiseLastOSError;
 inherited Create(False);
 Priority := tpIdle;
end;

destructor TLogFileThread.Destroy;
begin
 CloseHandle(FWorkEvent);
 inherited;
end;



> А эта проверка зачем ?


Соответственно, проверки убрал.


> Игорь Шевченко ©   (09.12.05 16:14) [40]


Спасибо!

Может еще у кого-нибудь замечания будут?


 
Leonid Troyanovsky ©   (2005-12-09 17:44) [43]


> Владислав ©   (09.12.05 16:35) [42]

>  CloseHandle(FWorkEvent);


if FWorkEvent <> 0 then
 CloseHandle(FWorkEvent);

Кста, удобно Win32Check(..).
Ну, если уж на Windows ориентироваться.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2005-12-09 18:00) [44]

> Владислав ©   (09.12.05 14:25) [33]

Я вот чего-то не понял, поток занят лишь FlushFileBuffers,
и делает это синхронно (это правильно).
Но, почему, собс-но, первичному потоку оное не делать самому.

--
Regards, LVT.


 
Deka ©   (2005-12-09 18:11) [45]

А я наверное сделал бы так:
1. Задался максимальной длиной строки в логе + маркер последней.
2. Определился с числом строк.
3. Создал файл соотвествующего размера (для хранения всех записей).
4. Записывал очередную строку с маркером, а у предыдущей маркер сбрасывал.
5. При достижении конца файла (лога) запись продолжается с первой позиции.

Получается нестандартный формат файла, для которого понадобится написать коротенький вьювер. Хотя можно и так посмотреть.

В плюсах скорость записи и минимум необходимой памяти.
В минусах удобочитаемость.

Вот такой вот набросок.
Возможны варианты с номером записи последней записи в первой строке лога и т.п.


 
TUser ©   (2005-12-09 19:05) [46]

А я бы 2 файла сделал и писал бы в них.


 
Владислав ©   (2005-12-10 15:45) [47]


> Leonid Troyanovsky ©   (09.12.05 18:00) [44]
> > Владислав ©   (09.12.05 14:25) [33]
>
> Я вот чего-то не понял, поток занят лишь FlushFileBuffers,
>
> и делает это синхронно (это правильно).
> Но, почему, собс-но, первичному потоку оное не делать самому.
>


Это, конечно, было бы проще, но как Вы себе это представляете? Я что-то не вижу вариантов.


> Deka ©   (09.12.05 18:11) [45]
> В минусах удобочитаемость.


Это очень весомый минус. Есть устоявшийся интерфейс. Ломать его нельзя. Поэтому файл должен быть читаем в любом обычном редакторе.


> TUser ©   (09.12.05 19:05) [46]
> А я бы 2 файла сделал и писал бы в них.


Я же не спорю. Это, пожалуй, самый рациональный вариант. Но уже давно существует система, которую сломать нельзя (не в моих силах). Поэтому пляшем от того, что есть. А есть один лог-файл, который пользователь может просмотреть любым, удобным ему средством.


 
Deka ©   (2005-12-12 10:59) [48]

В принципе можно программу-просмотрщик не делать. Тогда просто придется читать также, как и записывалось. Т.е. Читаешь от метки последней записи вниз, а достигнув конца лога переходишь к первой строке и читаешь до метки последней записи. Женщинам правда наверное сложно придется ;)


 
Verg ©   (2005-12-12 11:38) [49]

interface
 procedure StoreLogString(Log, Strng : PChar; MaxSize : integer);

implementation
uses Windows, SysUtils, SyncObjs, Math;

var LogCs : TCriticalSection;

procedure StoreLogString(Log, Strng : PChar; MaxSize : integer);
var F : Text;
   Fs : file;
   sLog, sStr : string;
   FSize : integer;
   Buffer : pchar;
   bufSize : integer;
   Rp, Wp : integer;
   Readed : integer;
begin
 sLog:=Log;
 sStr:=Strng;
 LogCs.Enter;
 try
   if MaxSize<>0 then
   begin
     Assign(Fs, sLog);
     try
       reset(Fs, 1);
       try
         FSize:=FileSize(Fs);
         if FSize>MaxSize then
         begin
           BufSize:=Min(Max(((3*MaxSize) div 4)+1, 4096),256*1024);
           GetMem(Buffer, BufSize);
           try
             Rp:=FSize-((3*MaxSize) div 4);
             Wp:=0;
             repeat
               Seek(Fs, Rp);
               BlockRead(Fs,Buffer^,BufSize, Readed);
               Rp:=FilePos(Fs);
               if Readed>0 then
               begin
                 Seek(Fs, Wp);
                 BlockWrite(Fs, Buffer^, Readed);
                 Wp:=FilePos(Fs);
               end;
             until Readed<=0;
             Seek(Fs, Wp);
             Truncate(Fs);
           finally
             FreeMem(Buffer);
           end;
         end;
       finally
         Close(Fs);
       end;
     except
     end;
   end;
   Assign(F, sLog);
   if FileExists(sLog) then Append(F) else Rewrite(F);
   try
     writeln(F, sStr);
   finally
     Close(F);
   end;
 finally
   LogCs.Leave;
 end;
end;

initialization

 LogCs:=TCriticalSection.Create;

finalization
 Logcs.Free;
 LogCs:=nil;

end.



Страницы: 1 2 вся ветка

Текущий архив: 2006.01.15;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.032 c
1-1134061576
Леонид Федьков
2005-12-08 20:06
2006.01.15
Нажатие Caps Lock из программы


6-1127822981
arhis
2005-09-27 16:09
2006.01.15
Исходящий траффик TServerSocket


2-1135582359
ksu
2005-12-26 10:32
2006.01.15
прозрачный фон TLabel


14-1135188322
MisterASM
2005-12-21 21:05
2006.01.15
ассемблер


11-1116329995
apus
2005-05-17 15:39
2006.01.15
Вышел Free Pascal 2.0