?? logshow.pas
字號:
unit LogShow;
interface
uses
SysUtils, Classes,UnitWriteLogThread,ULogFrm;
type
TLogShow = class(TComponent)
private
{ Private declarations }
LogList : TThreadList ;
LogThread :TWriteLogThread ;
function GetLogFileName:Shortstring;
procedure AddLogToList(Log,LogSource:ShortString;LobLevel:TLogLevel);
function GetNextLog:PLogRecord;
Procedure RemoveLogInList(Log:PLogRecord);
procedure WriteLogFileAll ;overload;
function WriteLogFileALL(FileName:ShortString):boolean;overload;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create;
destructor destroy;override;
function StartWriteLogThread : TWriteLogThread;
function StopWriteLogThread:boolean;
procedure MemoryToTxtFile(Mess:pchar; start, pCharLength:integer);
published
{ Published declarations }
end;
procedure Register;
implementation
{-------------------------------------------------------------------------------
過程名: MemoryToTxtFile
作者: fengfan
日期: 2004.11.10
說明: 將一段內存以字節的方式保存到文件中,而不管這個字節是否可見。
參數: Mess:pchar; start, Length:integer
返回值: 無
-------------------------------------------------------------------------------}
procedure TLogShow.MemoryToTxtFile(Mess:pchar; start, pCharLength:integer);
var
ExeName,FileName,ExtName,FilePath:ShortString;
i:integer;
MemoryStream :TMemoryStream ;
FileNameLength :Integer;
begin
ExtName := ExtractFileExt(Application.ExeName);
FileName := ExtractFileName(Application.ExeName);
FileNameLength := Length(FileName)-Length(ExtName) ;
ExeName := Copy(FileName,1,FileNameLength);
FilePath := ExtractFilePath(Application.ExeName);
filename:=FilePath+'log\'+ExeName+formatdatetime('YYYYMMDDHHSSNN',Now);
i := 0 ;
while FileExists(FileName) do
begin
FileName := FileName + IntToStr(i);
inc(i);
end;
MemoryStream := TMemoryStream.Create ;
try
MemoryStream.Write(Mess[Start],pCharLength);
MemoryStream.SaveToFile(FileName);
finally
MemoryStream.free;
end;
end;
{-------------------------------------------------------------------------------
過程名: AddLogToList
作者: fengfan
日期: 2004.07.13
說明: 將一條日志記錄放入隊列中。
參數: Log:shortstring
20060827 修改
返回值: 無
-------------------------------------------------------------------------------}
procedure TLogShow.AddLogToList(Log,LogSource:ShortString;LobLevel:TLogLevel);
var
LogRecord:PLogRecord ;
begin
new(LogRecord) ;
FillChar(LogRecord.LogStr[0],sizeof(LogRecord.LogStr),#0);
StrPCopy(LogRecord.LogStr,Log);
FillChar(LogRecord.LogSource[0],sizeof(LogRecord.LogSource),#0);
StrPCopy(LogRecord.LogSource,LogSource);
LogRecord.LogTime := Now ;
LogRecord.LogLevel := LogLevel ;
LogList.Add(LogRecord);
end;
{-------------------------------------------------------------------------------
過程名: GetNextLog
作者: fengfan
日期: 2004.07.13
說明: 取日志隊列中第一條日志記錄
參數: 無
返回值: PLogRecord
-------------------------------------------------------------------------------}
function TLogShow.GetNextLog :PLogRecord;
var
vList :TList;
begin
Result := nil ;
if not Assigned(LogList) then exit ;
vList := LogList.LockList ;
try
if vList.Count > 0 then
begin
Result := PLogRecord(vList.items[0]);
end
else
begin
Result := nil;
end;
finally
LogList.UnlockList ;
end;
end;
{-------------------------------------------------------------------------------
過程名: RemoveLogInList
作者: fengfan
日期: 2004.07.13
說明: 從日志隊列中移除一條日志記錄
參數: Log:PLogRecord
返回值: 無
-------------------------------------------------------------------------------}
Procedure TLogShow.RemoveLogInList(Log:PLogRecord);
begin
if not Assigned(LogList) then exit ;
LogList.Remove(Log);
Dispose(Log);
end;
{-------------------------------------------------------------------------------
過程名: GetLogFileName
作者: fengfan
日期: 2004.07.13
說明: 取得日志文件名 格式為:'路徑'+'文件名'+'日期'+'_log'+'.txt'
參數: 無
返回值: shortstring
-------------------------------------------------------------------------------}
function TLogShow.GetLogFileName: shortstring;
var
ExeName,FileName,ExtName,FilePath:ShortString;
begin
ExtName := ExtractFileExt(Application.ExeName);
FileName := ExtractFileName(Application.ExeName);
ExeName := Copy(FileName,1,Length(FileName)-Length(ExtName));
FilePath := ExtractFilePath(Application.ExeName);
result:=FilePath+'log\'+ExeName+datetostr(date)+'_log.html';
end;
{-------------------------------------------------------------------------------
過程名: WriteLogFileAll
作者: fengfan
日期: 2004.07.13
說明: 一次性將LogList中的文件寫入日志文件,如果日志文件不存在,
則釋放日志占用內存
參數: 無
返回值: 無
-------------------------------------------------------------------------------}
procedure TLogShow.WriteLogFileAll;
var
FileName:ShortString;
begin
FileName := GetLogFileName ;
if not WriteLogFileAll(FileName) then
begin
FileName := copy(FileName,1,Length(FileName) - 3 ) + 'bak';
if not WriteLogFileAll(FileName) then
begin
ShowMessage('保存日志數據失敗!'+#13+#13+#13+#13+#13+#13+#13+#13);
end;
end;
end;
function TLogShow.WriteLogFileALL(FileName:ShortString):boolean;
var
LogStr:ShortString;
LogFile :TextFile ;
LogRecord :PLogRecord ;
vList : TList ;
TryNum,FileHanel : integer;
begin
FileHanel := 0 ;
if not FileExists(FileName) then
begin
FileHanel := FileCreate(FileName);
end;
if FileHanel = -1 then
begin
vList := LogList.LockList ;
try
while vList.Count >0 do
begin
LogRecord:= PLogRecord(vList.Items[0]);
vList.Remove(LogRecord);
Dispose(LogRecord);
end;
finally
LogList.UnlockList ;
end;
Result := true ;
Exit;
end
else
FileClose(FileHanel);
AssignFile(LogFile,FileName);
vList := LogList.LockList ;
Append(LogFile);
try
TryNum := 0 ;
while vList.Count >0 do
begin
LogRecord:= PLogRecord(vList.Items[0]);
LogStr := (datetimetostr(LogRecord.LogTime)+':'+LogRecord.LogStr) ;
try
writeln(LogFile,LogStr);
vList.Remove(LogRecord);
Dispose(LogRecord);
TryNum := 0 ;
except
on e:Exception do
begin
AddLogToListA('寫入日志文件失敗!'+e.Message,LogError);
inc(TryNum);
end;
end;
if TryNum > 10 then
begin
Sleep(1000);
Result := False ;
exit;
end;
end;
finally
LogList.UnlockList ;
CloseFile(LogFile);
end;
Result := true ;
end;
{-------------------------------------------------------------------------------
過程名: StartWriteLogThread
作者: fengfan
日期: 2004.07.13
說明: 啟動日志線程
參數: memo:TMemo
返回值: TWriteLogThread
-------------------------------------------------------------------------------}
function TLogShow.StartWriteLogThread :TWriteLogThread;
begin
if LogList <> nil then
//memo.Lines.Add('日志隊列已經建立!')
else
LogList := TThreadList.Create ;
if LogThread <> nil then
begin
//memo.Lines.Add('寫日志線程已經存在');
Result := LogThread;
exit;
end;
LogThread := TWriteLogThread.create(True);
try
LogThread.Priority := tpLowest ;
LogThread.Resume ;
//AddLogToList('寫日志線程成功啟動!');
result := LogThread ;
except
on e:exception do
begin
AddLogToList('寫日志線程啟動失敗,錯誤信息為:'+E.Message);
Result := Nil;
exit ;
end;
end;
end;
{-------------------------------------------------------------------------------
過程名: StopWriteLogThread
作者: fengfan
日期: 2004.07.13
說明: 停止寫日志線程,并將日志List中沒有寫入日志文件的日志寫入日志文件
參數: WriteLogThread :TWriteLogThread
返回值: boolean
-------------------------------------------------------------------------------}
function TLogShow.StopWriteLogThread:boolean;
var
i :integer;
begin
if Assigned(LogThread) then
begin
LogThread.Terminate ;
i := 0 ;
while true do
begin
sleep(1000);
if LogThread.Terminated then
begin
Sleep(1000);
FreeAndNil(LogThread);
break;
end;
inc(i);
if i > 6 then break ;
end;
end;
if Assigned(LogList) then
begin
i := LogList.LockList.Count;
LogList.UnlockList;
if i >0 then WriteLogFileAll ;
FreeAndNil(LogList);
end;
Result := True ;
end;
procedure Register;
begin
RegisterComponents('Samples', [TLogShow]);
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -