delphi ,日志class,临界区,文件操作
如果你引用或者修改以下代码 请不要去掉注释,这个涉及到一个程序员的职业道德问题
转载请注明
/** 本代码为日志class
* 作者:刘昆
* 最后修改日期: 2004-9-23
* 以上代码免费,若直接引用一下代码请告知,并保留此注释
* 作为一名程序员应该有最基本的职业道德*/
unit pushLog;
interface
uses classes, sysutils, windows;
var
ThreadLock: TRTLCriticalSection; //临界区
const PathDelim = '\';
DriveDelim = ':';
type
Tlog = class
private
//logfile: file;
fileName: string;
function dirExist(const DirName: string): boolean;
function getDirName(const fileName: string): string;
function LastDelimiter(const Delimiters, S: string): Integer;
procedure createLogDir();
public
constructor Create(const filename: string);
destructor Destroy(); override;
procedure addLog(p: Pchar);
end;
implementation
{ Tlog }
procedure Tlog.addLog(p: Pchar);
var log_Line: pchar;
log_len: integer;
handle: Thandle;
des_Len: longword;
begin
EnterCriticalSection(ThreadLock);
log_Line := nil;
handle := $0;
des_Len := $0;
try
createLogDir;
log_len := strlen(p);
getmem(log_Line, log_len);
strcopy(log_Line, p);
handle := createfile(
pchar(fileName), //文件名
GENERIC_READ or GENERIC_WRITE, //期望存取模式 通用读写
FILE_SHARE_READ or FILE_SHARE_WRITE, //共享模式
nil, //定义文件安全特性的指针(前提:操作系统支持)。
OPEN_ALWAYS, //打开和创建文件方式。
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, //要打开文件的标志和属性(如:隐藏,系统等)。
0); //模板文件句柄
if handle <> INVALID_HANDLE_VALUE then begin
SetFilePointer(handle, 0, nil, FILE_END);
WriteFile(handle, log_Line^, log_len, des_Len, nil);
end;
finally
CloseHandle(handle);
freeMem(log_Line);
LeaveCriticalSection(ThreadLock);
end;
end;
constructor Tlog.Create(const filename: string);
begin
self.fileName := filename;
end;
procedure Tlog.createLogDir;
var dir_Name: string;
begin
dir_Name := getDirName(fileName) + '\log';
if not DirExist(dir_Name) then begin //检测日志目录是否存在
mkdir(dir_Name);
end;
end;
destructor Tlog.Destroy;
begin
inherited;
end;
function Tlog.DirExist(const DirName: string): boolean;
var
Handle: THandle;
FindData: TWin32FindData;
begin
result := false;
Handle := FindFirstFile(PChar(DirName), FindData);
if Handle <> INVALID_HANDLE_VALUE then begin
FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = $10 then begin
result := true;
end;
end;
end;
function Tlog.getDirName(const fileName: string): string;
var
I: Integer;
begin
I := LastDelimiter(':\', Filename);
if (I > 1) and (FileName[I] = PathDelim) and (((FileName[I - 1]
<> PathDelim) and (FileName[I - 1] <> DriveDelim)) or
(ByteType(FileName, I - 1) = mbTrailByte)) then
Dec(I);
while (ByteType(FileName, I - 1) = mbTrailByte) and (I > 0) do
Dec(I);
Result := Copy(FileName, 1, I);
end;
function Tlog.LastDelimiter(const Delimiters, S: string): Integer;
var
P: PChar;
begin
Result := Length(S);
P := PChar(Delimiters);
while Result > 0 do
begin
if (S[Result] <> #0) and (StrScan(P, S[Result]) <> nil) then // 检测最后一个字符是否为 '\'或者':'
if (ByteType(S, Result) = mbTrailByte) then
Dec(Result)
else
Exit;
Dec(Result);
end;
end;
initialization
InitializeCriticalSection(ThreadLock);
finalization
DeleteCriticalSection(ThreadLock);
end.
调用方法
procedure TMain.Button1Click(Sender: TObject);
var
log: Tlog;
begin
log := Tlog.Create(ExtractFileDir(Application.Exename) + '\' + 'aa.log');
log.addLog(pchar('好的' + #13#10));
log.addLog(pchar('aaaaaaaaaaaaaaaaaaaa' + #13#10));
log.Free;
end;