Форум: "Основная";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];
ВнизРеализация лог-файла. Найти похожие ветки
← →
Игорь Шевченко © (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;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.016 c