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

简介: 1.日志基类 .h文件//--------------------------------------------------------------------------- #ifndef UnitLogWriterH #define UnitLogWriterH #include ...

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;
}
//---------------------------------------------------------------------------
 
相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
11月前
|
C++
基本二叉树与排序二叉树(C++源码)
本程序实现二叉树基本操作与二叉排序树应用。支持前序建树、四种遍历、求深度、叶子数、第K层节点数及查找功能;并实现二叉排序树的构建、中序输出与查找比较次数统计,分析不同插入顺序对树形态和查找效率的影响。
|
11月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
534 1
|
11月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
469 1
|
12月前
|
存储 缓存 监控
用 C++ 红黑树给公司电脑监控软件的日志快速排序的方法
本文介绍基于C++红黑树算法实现公司监控电脑软件的日志高效管理,利用其自平衡特性提升日志排序、检索与动态更新效率,并结合实际场景提出优化方向,增强系统性能与稳定性。
268 4
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
637 12
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
352 0
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
544 0
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
567 83

热门文章

最新文章