撰写日志类
/**/
/*
Log File Library(WIN98/NT/2000)
Compile by: BC++ 5; C++ BUILDER; VC++; VC.NET;
copyright(c) 2004.5 - 2005.3 llbird [email protected] http://blog.csdn.net/wujian53
*/
/**/ /*
Use:
//这个代码我用工业现场24X7值守的程序纪录各种信息, 简单易用;
//一般用一个全局日志对象, 有临界排斥可以多线程安全使用。
//有两个类
class LogFile;//用户定义日志文件名
class LogFileEx;//有日志文件名自动生成功能 , 可分年月日频率生成文件名, 可指定日志存放的目录
LogFile gLog("My.Log");
gLog.Log("test", 4);//记录日志
gLog.Log("系统启动");
LogFileEx gLog(".", LogFileEx :: YEAR);//一年生成一个日志文件
LogFileEx gLog(".\\Log", LogFileEx :: MONTH);//一月生成一个日志文件
LogFileEx gLog(".\\Log", LogFileEx :: DAY);//一天生成一个日志文件
//注意日志所属目录创建失败会自动退出, 请注意目录的合法性, 文件生成频率看情况掌握
//24小时运行的程序可以每天生成一个日志文件, 以免内容过多
*/
#ifndef _LOGFILE_H
#define _LOGFILE_H
#include < assert.h >
#include < time.h >
#include < stdio.h >
#include < windows.h >
class LogFile
{
protected :
CRITICAL_SECTION _csLock;
char * _szFileName;
HANDLE _hFile;
bool OpenFile() // 打开文件, 指针到文件尾
{
if (IsOpen())
return true ;
if ( ! _szFileName)
return false ;
_hFile = CreateFile(
_szFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if ( ! IsOpen() && GetLastError() == 2 ) // 打开不成功, 且因为文件不存在, 创建文件
_hFile = CreateFile(
_szFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (IsOpen())
SetFilePointer(_hFile, 0 , NULL, FILE_END);
return IsOpen();
}
DWORD Write(LPCVOID lpBuffer, DWORD dwLength)
{
DWORD dwWriteLength = 0 ;
if (IsOpen())
WriteFile(_hFile, lpBuffer, dwLength, & dwWriteLength, NULL);
return dwWriteLength;
}
virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength) // 写日志, 可以扩展修改
{
time_t now;
char temp[ 21 ];
DWORD dwWriteLength;
if (IsOpen())
{
time( & now);
strftime(temp, 20 , " %Y-%m-%d %H:%M:%S " , localtime( & now));
WriteFile(_hFile, " \xd\xa#----------------------------- " , 32 , & dwWriteLength, NULL);
WriteFile(_hFile, temp, 19 , & dwWriteLength, NULL);
WriteFile(_hFile, " -----------------------------#\xd\xa " , 32 , & dwWriteLength, NULL);
WriteFile(_hFile, lpBuffer, dwLength, & dwWriteLength, NULL);
WriteFile(_hFile, " \xd\xa " , 2 , & dwWriteLength, NULL);
FlushFileBuffers(_hFile);
}
}
void Lock() { ::EnterCriticalSection( & _csLock); }
void Unlock() { ::LeaveCriticalSection( & _csLock); }
public :
LogFile( const char * szFileName = " Log.log " ) // 设定日志文件名
{
_szFileName = NULL;
_hFile = INVALID_HANDLE_VALUE;
::InitializeCriticalSection( & _csLock);
SetFileName(szFileName);
}
virtual ~ LogFile()
{
::DeleteCriticalSection( & _csLock);
Close();
if (_szFileName)
delete []_szFileName;
}
const char * GetFileName()
{
return _szFileName;
}
void SetFileName( const char * szName) // 修改文件名, 同时关闭上一个日志文件
{
assert(szName);
if (_szFileName)
delete []_szFileName;
Close();
_szFileName = new char [strlen(szName) + 1 ];
assert(_szFileName);
strcpy(_szFileName, szName);
}
bool IsOpen()
{
return _hFile != INVALID_HANDLE_VALUE;
}
void Close()
{
if (IsOpen())
{
CloseHandle(_hFile);
_hFile = INVALID_HANDLE_VALUE;
}
}
void Log(LPCVOID lpBuffer, DWORD dwLength) // 追加日志内容
{
assert(lpBuffer);
__try
{
Lock();
if ( ! OpenFile())
return ;
WriteLog(lpBuffer, dwLength);
}
__finally
{
Unlock();
}
}
void Log( const char * szText)
{
Log(szText, strlen(szText));
}
private : // 屏蔽函数
LogFile( const LogFile & );
LogFile & operator = ( const LogFile & );
} ;
class LogFileEx : public LogFile
{
protected :
char * _szPath;
char _szLastDate[ 9 ];
int _iType;
void SetPath( const char * szPath)
{
assert(szPath);
WIN32_FIND_DATA wfd;
char temp[MAX_PATH + 1 ] = { 0 } ;
if (FindFirstFile(szPath, & wfd) == INVALID_HANDLE_VALUE && CreateDirectory(szPath, NULL) == 0 )
{
strcat(strcpy(temp, szPath), " Create Fail. Exit Now! Error ID : " );
ltoa(GetLastError(), temp + strlen(temp), 10 );
MessageBox(NULL, temp, " Class LogFileEx " , MB_OK);
exit( 1 );
}
else
{
GetFullPathName(szPath, MAX_PATH, temp, NULL);
_szPath = new char [strlen(temp) + 1 ];
assert(_szPath);
strcpy(_szPath, temp);
}
}
public :
enum LOG_TYPE {YEAR = 0 , MONTH = 1 , DAY = 2 } ;
LogFileEx( const char * szPath = " . " , LOG_TYPE iType = MONTH)
{
_szPath = NULL;
SetPath(szPath);
_iType = iType;
memset(_szLastDate, 0 , 9 );
}
~ LogFileEx()
{
if (_szPath)
delete []_szPath;
}
const char * GetPath()
{
return _szPath;
}
void Log(LPCVOID lpBuffer, DWORD dwLength)
{
assert(lpBuffer);
char temp[ 10 ];
static const char format[ 3 ][ 10 ] = { " %Y " , " %Y-%m " , " %Y%m%d " } ;
__try
{
Lock();
time_t now = time(NULL);
strftime(temp, 9 , format[_iType], localtime( & now));
if (strcmp(_szLastDate, temp) != 0 ) // 更换文件名
{
strcat(strcpy(_szFileName, _szPath), " \\ " );
strcat(strcat(_szFileName, temp), " .log " );
strcpy(_szLastDate, temp);
Close();
}
if ( ! OpenFile())
return ;
WriteLog(lpBuffer, dwLength);
}
__finally
{
Unlock();
}
}
void Log( const char * szText)
{
Log(szText, strlen(szText));
}
private : // 屏蔽函数
LogFileEx( const LogFileEx & );
LogFileEx & operator = ( const LogFileEx & );
} ;
#endif
Log File Library(WIN98/NT/2000)
Compile by: BC++ 5; C++ BUILDER; VC++; VC.NET;
copyright(c) 2004.5 - 2005.3 llbird [email protected] http://blog.csdn.net/wujian53
*/
/**/ /*
Use:
//这个代码我用工业现场24X7值守的程序纪录各种信息, 简单易用;
//一般用一个全局日志对象, 有临界排斥可以多线程安全使用。
//有两个类
class LogFile;//用户定义日志文件名
class LogFileEx;//有日志文件名自动生成功能 , 可分年月日频率生成文件名, 可指定日志存放的目录
LogFile gLog("My.Log");
gLog.Log("test", 4);//记录日志
gLog.Log("系统启动");
LogFileEx gLog(".", LogFileEx :: YEAR);//一年生成一个日志文件
LogFileEx gLog(".\\Log", LogFileEx :: MONTH);//一月生成一个日志文件
LogFileEx gLog(".\\Log", LogFileEx :: DAY);//一天生成一个日志文件
//注意日志所属目录创建失败会自动退出, 请注意目录的合法性, 文件生成频率看情况掌握
//24小时运行的程序可以每天生成一个日志文件, 以免内容过多
*/
#ifndef _LOGFILE_H
#define _LOGFILE_H
#include < assert.h >
#include < time.h >
#include < stdio.h >
#include < windows.h >
class LogFile
{
protected :
CRITICAL_SECTION _csLock;
char * _szFileName;
HANDLE _hFile;
bool OpenFile() // 打开文件, 指针到文件尾
{
if (IsOpen())
return true ;
if ( ! _szFileName)
return false ;
_hFile = CreateFile(
_szFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if ( ! IsOpen() && GetLastError() == 2 ) // 打开不成功, 且因为文件不存在, 创建文件
_hFile = CreateFile(
_szFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (IsOpen())
SetFilePointer(_hFile, 0 , NULL, FILE_END);
return IsOpen();
}
DWORD Write(LPCVOID lpBuffer, DWORD dwLength)
{
DWORD dwWriteLength = 0 ;
if (IsOpen())
WriteFile(_hFile, lpBuffer, dwLength, & dwWriteLength, NULL);
return dwWriteLength;
}
virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength) // 写日志, 可以扩展修改
{
time_t now;
char temp[ 21 ];
DWORD dwWriteLength;
if (IsOpen())
{
time( & now);
strftime(temp, 20 , " %Y-%m-%d %H:%M:%S " , localtime( & now));
WriteFile(_hFile, " \xd\xa#----------------------------- " , 32 , & dwWriteLength, NULL);
WriteFile(_hFile, temp, 19 , & dwWriteLength, NULL);
WriteFile(_hFile, " -----------------------------#\xd\xa " , 32 , & dwWriteLength, NULL);
WriteFile(_hFile, lpBuffer, dwLength, & dwWriteLength, NULL);
WriteFile(_hFile, " \xd\xa " , 2 , & dwWriteLength, NULL);
FlushFileBuffers(_hFile);
}
}
void Lock() { ::EnterCriticalSection( & _csLock); }
void Unlock() { ::LeaveCriticalSection( & _csLock); }
public :
LogFile( const char * szFileName = " Log.log " ) // 设定日志文件名
{
_szFileName = NULL;
_hFile = INVALID_HANDLE_VALUE;
::InitializeCriticalSection( & _csLock);
SetFileName(szFileName);
}
virtual ~ LogFile()
{
::DeleteCriticalSection( & _csLock);
Close();
if (_szFileName)
delete []_szFileName;
}
const char * GetFileName()
{
return _szFileName;
}
void SetFileName( const char * szName) // 修改文件名, 同时关闭上一个日志文件
{
assert(szName);
if (_szFileName)
delete []_szFileName;
Close();
_szFileName = new char [strlen(szName) + 1 ];
assert(_szFileName);
strcpy(_szFileName, szName);
}
bool IsOpen()
{
return _hFile != INVALID_HANDLE_VALUE;
}
void Close()
{
if (IsOpen())
{
CloseHandle(_hFile);
_hFile = INVALID_HANDLE_VALUE;
}
}
void Log(LPCVOID lpBuffer, DWORD dwLength) // 追加日志内容
{
assert(lpBuffer);
__try
{
Lock();
if ( ! OpenFile())
return ;
WriteLog(lpBuffer, dwLength);
}
__finally
{
Unlock();
}
}
void Log( const char * szText)
{
Log(szText, strlen(szText));
}
private : // 屏蔽函数
LogFile( const LogFile & );
LogFile & operator = ( const LogFile & );
} ;
class LogFileEx : public LogFile
{
protected :
char * _szPath;
char _szLastDate[ 9 ];
int _iType;
void SetPath( const char * szPath)
{
assert(szPath);
WIN32_FIND_DATA wfd;
char temp[MAX_PATH + 1 ] = { 0 } ;
if (FindFirstFile(szPath, & wfd) == INVALID_HANDLE_VALUE && CreateDirectory(szPath, NULL) == 0 )
{
strcat(strcpy(temp, szPath), " Create Fail. Exit Now! Error ID : " );
ltoa(GetLastError(), temp + strlen(temp), 10 );
MessageBox(NULL, temp, " Class LogFileEx " , MB_OK);
exit( 1 );
}
else
{
GetFullPathName(szPath, MAX_PATH, temp, NULL);
_szPath = new char [strlen(temp) + 1 ];
assert(_szPath);
strcpy(_szPath, temp);
}
}
public :
enum LOG_TYPE {YEAR = 0 , MONTH = 1 , DAY = 2 } ;
LogFileEx( const char * szPath = " . " , LOG_TYPE iType = MONTH)
{
_szPath = NULL;
SetPath(szPath);
_iType = iType;
memset(_szLastDate, 0 , 9 );
}
~ LogFileEx()
{
if (_szPath)
delete []_szPath;
}
const char * GetPath()
{
return _szPath;
}
void Log(LPCVOID lpBuffer, DWORD dwLength)
{
assert(lpBuffer);
char temp[ 10 ];
static const char format[ 3 ][ 10 ] = { " %Y " , " %Y-%m " , " %Y%m%d " } ;
__try
{
Lock();
time_t now = time(NULL);
strftime(temp, 9 , format[_iType], localtime( & now));
if (strcmp(_szLastDate, temp) != 0 ) // 更换文件名
{
strcat(strcpy(_szFileName, _szPath), " \\ " );
strcat(strcat(_szFileName, temp), " .log " );
strcpy(_szLastDate, temp);
Close();
}
if ( ! OpenFile())
return ;
WriteLog(lpBuffer, dwLength);
}
__finally
{
Unlock();
}
}
void Log( const char * szText)
{
Log(szText, strlen(szText));
}
private : // 屏蔽函数
LogFileEx( const LogFileEx & );
LogFileEx & operator = ( const LogFileEx & );
} ;
#endif