c++ 多线程写日志的一个很实用的日志类源码(支持 c++ builder)

1.日志基类

.h文件

//---------------------------------------------------------------------------
#ifndef UnitLogWriterH
#define UnitLogWriterH
#include <vcl.h>
#include <time.h>
#include <assert.h>
//---------------------------------------------------------------------------
class LogFile
{
protected:
    CRITICAL_SECTION _csLock;
    char * _szFileName;
    HANDLE _hFile;
    bool OpenFile();//打开文件, 指针到文件尾
    DWORD Write(LPCVOID lpBuffer, DWORD dwLength);
    virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength);//写日志, 可以扩展修改
    void Lock()   { ::EnterCriticalSection(&_csLock); }
    void Unlock() { ::LeaveCriticalSection(&_csLock); }
public:
    LogFile(const char *szFileName = "Log.log");//设定日志文件名
    virtual ~LogFile();
    const char * GetFileName()
    {
       return _szFileName;
    }

    void SetFileName(const char *szName);//修改文件名, 同时关闭上一个日志文件
    bool IsOpen()
    {
       return _hFile != INVALID_HANDLE_VALUE;
    }

    void Close();

    void Log(LPCVOID lpBuffer, DWORD dwLength);//追加日志内容

    void Log(const char *szText)
    {
       Log(szText, strlen(szText));
    }
private://屏蔽函数
    LogFile(const LogFile&);
    LogFile&operator = (const LogFile&);
};
#endif

 

 

基类cpp文件

//---------------------------------------------------------------------------

#pragma hdrstop

#include "UnitLogWriter.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
LogFile::LogFile(const char *szFileName)
{
   _szFileName = NULL;
   _hFile = INVALID_HANDLE_VALUE;
   ::InitializeCriticalSection(&_csLock);

   SetFileName(szFileName);
}
//-------------------------------------------------------------------------
LogFile::~LogFile()
{
    ::DeleteCriticalSection(&_csLock);
    Close();

    if(_szFileName)
        delete []_szFileName;
}
//-------------------------------------------------------------------------

bool LogFile::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 LogFile::Write(LPCVOID lpBuffer, DWORD dwLength)
{
    DWORD dwWriteLength = 0;
    if(IsOpen())
        WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);
    return dwWriteLength;
}
//-------------------------------------------------------------------------
void LogFile::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 LogFile::SetFileName(const char *szName)
{
       assert(szName);

       if(_szFileName)
        delete []_szFileName;

       Close();

       _szFileName = new char[strlen(szName) + 1];
       assert(_szFileName);
       strcpy(_szFileName, szName);
}
//-------------------------------------------------------------------------
void LogFile::Close()
{
       if(IsOpen())
       {
        CloseHandle(_hFile);
        _hFile = INVALID_HANDLE_VALUE;
       }
}
//-------------------------------------------------------------------------
void LogFile::Log(LPCVOID lpBuffer, DWORD dwLength)
{
       assert(lpBuffer);
       __try
       {
        Lock();

        if(!OpenFile())
         return;

        WriteLog(lpBuffer, dwLength);
       }
       __finally
       {
        Unlock();
       }
}
 

2.日志派生类

.h文件

//---------------------------------------------------------------------------

#ifndef LogFileExH
#define LogFileExH
#include <assert.h>

#include "UnitLogWriter.h"

//---------------------------------------------------------------------------
class LogFileEx : public LogFile
{
protected:
    char *_szPath;
    char _szLastDate[9];
    int _iType;
    void SetPath(const char *szPath);
public:
    enum LOG_TYPE{YEAR = 0, MONTH = 1, DAY = 2};
    LogFileEx(const char *szPath = ".", LOG_TYPE iType = MONTH);
    ~LogFileEx();
    const char * GetPath();
    void Log(LPCVOID lpBuffer, DWORD dwLength);
    void Log(const char *szText);
    void Log(const AnsiString&szText);
private://屏蔽函数
    LogFileEx(const LogFileEx&);
    LogFileEx&operator = (const LogFileEx&);
};
#endif
 
cpp文件
 
//---------------------------------------------------------------------------

#pragma hdrstop

#include "LogFileEx.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
//-------------------------------------------------------------------------

void LogFileEx::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);
       }
}
//-------------------------------------------------------------------------
LogFileEx::LogFileEx(const char *szPath , LOG_TYPE iType)
{
   _szPath = NULL;
   SetPath(szPath);
   _iType = iType;
   memset(_szLastDate, 0, 9);
}
//-------------------------------------------------------------------------
LogFileEx::~LogFileEx()
{
   if(_szPath)
    delete []_szPath;
}
//-------------------------------------------------------------------------

const char * LogFileEx::GetPath()
{
   return _szPath;
}
//-------------------------------------------------------------------------

void LogFileEx::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 LogFileEx::Log(const char *szText)
{
   Log(szText, strlen(szText));
}
//-------------------------------------------------------------------------
void LogFileEx::Log(const AnsiString&szText)
{
    Log(szText.c_str(),szText.Length());
}

 

3.随便测试的代码

 

//---------------------------------------------------------------------------

#include <vcl.h>
#include <conio.h>
#include "LogFileEx.h"
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    LogFileEx log;
    log.Log("哈哈");
    AnsiString temp="adsfsadfsadfsaf";
    log.Log(temp);
    log.Log(temp);
    getch();
    return 0;
}
//---------------------------------------------------------------------------
 
时间: 2024-09-26 12:53:59

c++ 多线程写日志的一个很实用的日志类源码(支持 c++ builder)的相关文章

【实战HTML5与CSS3 第三篇】我第一个HTML5网页诞生了(提供源码)

原文 http://www.cnblogs.com/yexiaochai/archive/2013/05/01/3052782.html 目录 [实战HTML5与CSS3 第一篇]初探水深,美丽的导航,绚丽的图片爆炸!! [实战HTML5与CSS3 第二篇]绚丽的快速导航! [实战HTML5与CSS3 第三篇]我第一个HTML5网页诞生了(提供源码) 前言 昨天的进度有点延缓,只做了快速导航特效,都是晚上回来一点多才基本结束,其中很多问题也没有修正,就只有一个白板特效. 今天是假日的最后一天,所

推荐一个比较值得看的论坛源码..

问题描述 大家给推荐一个比较好的jsp论坛[源码]吧!自己想写个论坛,可网上太多,不知道选择哪个好,先研究一下!!先谢了... 解决方案 解决方案二:云网论坛CWBBS,google一下.解决方案三:找斑竹要CSDN的源码解决方案四:jlive解决方案五:jdon的不行吗?解决方案六:JspRun!社区论坛系统,免费的jsp开源论坛,java开源论坛,免费java论坛安全,功能强大,楼主可以去下载一个试试

app-想要一个图片合成的APP的源码

问题描述 想要一个图片合成的APP的源码 想要开发个APP,用户可以使用APP进行图片合成,生成一个新的图片,求源码

求一个java的人脸识别系统源码

问题描述 求一个java的人脸识别系统源码 用java语言开发,可以进行人脸识别的程序,算法不要太复杂,能进行简单的人脸识别就行了 解决方案 求人脸识别系统源代码!!! 解决方案二: 一个完整的项目demo http://download.csdn.net/detail/apbbbbb/9525308

socket-求一个C#的Webocket案列源码。

问题描述 求一个C#的Webocket案列源码. 求一个C#的Webocket案列源码.最好是能有即时通讯的那种.先谢谢了! 解决方案 参考codeplex开源项目WebSocket4Net项目首页有使用示例 解决方案二: http://stackoverflow.com/questions/10200910/create-hello-world-websocket-example 解决方案三: http://www.cnblogs.com/zformular/archive/2012/10/2

求一个C# P2P 远程控制的实例源码

问题描述 求一个C# P2P 远程控制的实例源码 A电脑想获得B电脑的远程桌面,通过服务器打洞.求有客户端和服务器端的实例源码. 解决方案 C# Winfrom实现远程控制http://blog.csdn.net/cnming/article/details/2686297 可以参考这个帖子http://bbs.csdn.net/topics/270075124 解决方案二: http://download.csdn.net/detail/newps/1698123 解决方案三: 直接用远程桌面

动手写一个Remoting接口测试工具(附源码下载)

      基于.NET开发分布式系统,经常用到Remoting技术.在测试驱动开发流行的今天,如果针对分布式系统中的每个Remoting接口的每个方法都要写详细的测试脚本,无疑非常浪费时间.所以,我想写一个能自动测试remoting接口的小工具InterfaceTester.而且,当分布式系统中的某个remoting接口出现bug时,该小工具可以提交需要模拟的数据,以便在调试remoting服务的环境中,快速定位和解决bug. InterfaceTester运行起来后的效果如下图:      

仿酷狗音乐播放器开发日志十八——换肤功能的实现二:改变控件和窗体透明度(附挂件类源码)

转载请说明原出处,谢谢~~          昨天把大致布局分析了一下,昨天晚上把布局写好实现了,今天把大致的功能完成了一下,现在的外观已经和原酷狗的换肤界面完全一样,其中的调整播放列表透明度和设置整个软件透明度的代码已经完成了,先把效果图贴一下,然后开发说开发过程.    开发步骤一:        布局的部分我就不说了,昨天已经分析了,只要用好素材,花点时间就能把界面效果做出来,其中"官方皮肤"和 "我的皮肤"调用CTabLayout可以实现两个界面的切换,如图

【自然框架】之鼠标点功能现(一):单表的增删改查(即上次5月23日活动的一个主题)【Demo、源码下载】

  简单的需求,点点鼠标就可以了,那么复杂的需求呢?还是要写代码,哈哈. 不要被我误导了哦,关于什么时候写代码的问题,请看这里:http://www.cnblogs.com/jyk/archive/2009/06/21/1507594.html    单表的增删改查         我有一个梦想,那就是不用敲代码,只需要点点鼠标,就可以实现客户的需求.       可能您会说这是不可能的,但是有个梦想总没有错吧.我就是想实现我的这个梦想,虽然可能一辈子都达不到,但是我还想努力一下子,不想让自己后