转自:
可按日期生成多个日志, 还可分年月日频率生成文件名
=====================================================================
/* Log File Library(WIN98/NT/2000)
Compile by: BC++ 5; C++ BUILDER; VC++; VC.NET;
copyright(c) 2004.5 - 2005.3 llbird wushaojian@21cn.com
*/ /* 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};
(责任编辑:admin) |