delphi ,日志class,臨界區(qū),文件操作

如果你引用或者修改以下代碼 請(qǐng)不要去掉注釋,這個(gè)涉及到一個(gè)程序員的職業(yè)道德問(wèn)題
轉(zhuǎn)載請(qǐng)注明
/** 本代碼為日志class
* 作者:劉昆
* 最后修改日期: 2004-9-23
* 以上代碼免費(fèi),若直接引用一下代碼請(qǐng)告知,并保留此注釋
* 作為一名程序員應(yīng)該有最基本的職業(yè)道德*/
unit pushLog;
interface
uses classes, sysutils, windows;
var
ThreadLock: TRTLCriticalSection; //臨界區(qū)
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, //期望存取模式 通用讀寫(xiě)
FILE_SHARE_READ or FILE_SHARE_WRITE, //共享模式
nil, //定義文件安全特性的指針(前提:操作系統(tǒng)支持)。
OPEN_ALWAYS, //打開(kāi)和創(chuàng)建文件方式。
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, //要打開(kāi)文件的標(biāo)志和屬性(如:隱藏,系統(tǒng)等)。
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 //檢測(cè)日志目錄是否存在
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 // 檢測(cè)最后一個(gè)字符是否為 '\'或者':'
if (ByteType(S, Result) = mbTrailByte) then
Dec(Result)
else
Exit;
Dec(Result);
end;
end;
initialization
InitializeCriticalSection(ThreadLock);
finalization
DeleteCriticalSection(ThreadLock);
end.
調(diào)用方法
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;