心扉美文

美文 > 经典日志 >

feeling的专栏

转自:

 

可按日期生成多个日志, 还可分年月日频率生成文件名

 

=====================================================================

 

/*
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)