前段时间自己写了一个日志类  不过是MFC写的   今天闲着没事  就用SDK重写了这个类  算是增加一点可移植性吧...
类的使用也很简单  初始化的时候传递一个日志名称  
然后在需要写日志的地方 直接调用这个对象的WriteLog函数传递一个字符串进去就行了
如果需要时间戳  则调用WriteLogWithTime函数  一样的接口
支持设置日志大小  SetLogSize()   //KB计算
代码很简单  一百来行  不过用着还算挺方便的  下午就用这个日志类找到了一个以前工程中的SQL相关联的BUG 呵呵  
.h文件
/*****************************************************
*文件名称: Log_SDK.h
*功能说明: 使用SDK + STL重写的一个日志类 增加可移植性
*创建时间: 09.10.31
*文件作者: zip
*****************************************************/
#pragma once
#include <string>
using namespace std;
class LogSDK
{
public:
    LogSDK(string strFileName);
    ~LogSDK(void);
    BOOL InitLogSDK();
    BOOL WriteLog(TCHAR* pContent);
    BOOL WriteLogWithTime(TCHAR* pContent);        //每次写一行 且带时间
    BOOL WriteLogAtFirstLine(TCHAR* pContent);    //将最近的日志写在最前面    
    void SetLogSize(int iSize);
private:
    HANDLE m_hFile;
    string m_strFileName;
    string m_strFormat; 
    CRITICAL_SECTION m_cs;                //临界区
    BOOL m_bInit;                            //初始化标志位
    int m_iSize;                                //文件大小    -- KB计算
    string GetTimeStr();
};
.cpp文件
/***************************************************
*文件名称: Log_SDK.cpp
*功能说明: LogSDK的实现文件
*创建时间: 09.10.31
*文件作者: zip
***************************************************/
#include "StdAfx.h"
#include ".\log_sdk.h"
LogSDK::LogSDK(string strFileName)
{
    m_bInit = FALSE;
    m_strFileName = strFileName;
    m_iSize = 20;    //默认20KB
    InitLogSDK();
}
LogSDK::~LogSDK(void)
{
    CloseHandle(m_hFile);
}
BOOL LogSDK::InitLogSDK()
{    
    m_hFile = CreateFile(m_strFileName.c_str() , GENERIC_ALL , 
        FILE_SHARE_WRITE , NULL ,  OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL);
    if (m_hFile == INVALID_HANDLE_VALUE)
    {
        DWORD dwErrorCode = GetLastError();
        TCHAR szErrMsg[255];
        sprintf(szErrMsg , "打开文件失败 , 错误代码:%d" , dwErrorCode);
        //AfxMessageBox(szErrMsg);
        MessageBox(NULL , szErrMsg , _T("警告") ,IDOK);
        return FALSE;
    }
    ::InitializeCriticalSection(&m_cs);    //初始化临界区
    m_bInit = TRUE;
    return TRUE;
}
//普通的写日志
BOOL LogSDK::WriteLog(TCHAR* pContent)
{
    ASSERT(m_bInit);
    DWORD dwFileLenHigh;
    DWORD dwFileLen = GetFileSize(m_hFile , &dwFileLenHigh);
    if (dwFileLen > (DWORD)m_iSize * 1024)    //文件过大 清空文件
    {
        SetFilePointer(m_hFile , 0 , NULL , FILE_BEGIN);    //移动文件指针
        SetEndOfFile(m_hFile);//清空文件
    }
    string strContent(pContent);
    strContent += "\r\n";
    BOOL bRet = TRUE;
    ::EnterCriticalSection(&m_cs);
    SetFilePointer(m_hFile , 0 , NULL , FILE_END);    //移动到文件末尾
    DWORD dwWriteLen;
    BOOL bSuccess = WriteFile(m_hFile , strContent.c_str() , 
        (DWORD)strContent.length() , &dwWriteLen , NULL);
    ASSERT(dwWriteLen == strContent.length());
    if (!bSuccess)
    {
        DWORD dwErrorCode = GetLastError();
        TCHAR szErrMsg[255];
        sprintf(szErrMsg , "写入日志文件失败 , 错误代码:%d" , dwErrorCode);        
        MessageBox(NULL , szErrMsg , _T("发生了严重的错误") , IDOK);
        bRet = FALSE;    //此处不用返回  还要释放临界区
    }
    ::LeaveCriticalSection(&m_cs);
    return bRet;
}
//带有时间戳的日志
BOOL LogSDK::WriteLogWithTime(TCHAR* pContent)
{
    ASSERT(m_bInit);
    DWORD dwFileLenHigh;
    DWORD dwFileLen = GetFileSize(m_hFile , &dwFileLenHigh);
    if (dwFileLen > (DWORD)m_iSize * 1024)    //文件过大 清空文件
    {
        SetFilePointer(m_hFile , 0 , NULL , FILE_BEGIN);    
        SetEndOfFile(m_hFile);//清空文件
    }
    //strcat(pContent , "\r\n");
    string strContent(pContent);
    strContent += "\r\n";
    strContent.insert(0 , "  ");
    strContent.insert(0 , GetTimeStr());
    BOOL bRet = TRUE;
    ::EnterCriticalSection(&m_cs);
    SetFilePointer(m_hFile , 0 , NULL , FILE_END);    //移动到文件末尾
    DWORD dwWriteLen;
    BOOL bSuccess = WriteFile(m_hFile , strContent.c_str() , 
        (DWORD)strContent.length() , &dwWriteLen , NULL);
    ASSERT(dwWriteLen == strContent.length());
    if (!bSuccess)
    {
        DWORD dwErrorCode = GetLastError();
        TCHAR szErrMsg[255];
        sprintf(szErrMsg , "写入日志文件失败 , 错误代码:%d" , dwErrorCode);        
        MessageBox(NULL , szErrMsg , _T("发生了严重的错误") , IDOK);
        bRet = FALSE;    //此处不用返回  还要释放临界区
    }
    ::LeaveCriticalSection(&m_cs);
    return bRet;
}
//返回格式化的时间字符串
string LogSDK::GetTimeStr()
{
    SYSTEMTIME sys;
    ::GetLocalTime(&sys);    //获取当前系统时间
    TCHAR szTime[64];
    memset(szTime , 0 , 64);
    sprintf(szTime , "%d-%02d-%02d %02d:%02d:%02d.%03d" , 
        sys.wYear , sys.wMonth , sys.wDay , sys.wHour , sys.wMinute , sys.wSecond , sys.wMilliseconds);
    return string(szTime);
}
void LogSDK::SetLogSize(int iSize)
{
    m_iSize = iSize;
}
也可以算锻炼一下API的操作吧...  
	
posted on 2009-10-31 17:58 
李佳 阅读(1187) 
评论(1)  编辑 收藏 引用  所属分类: 
WIN32 应用开发