zoukankan      html  css  js  c++  java
  • CLog3 写日志的类

    开始我的第一个vc模块的设计。

    这个是一个vc的写日志的类,为什么叫CLog3...因为之前有两版写log的类,但是都是用C#写的,所以这个vc写的就叫CLog3吧。

    功能只是简单模拟C#中的写Log的方法的设计。


    设计思路:

    因为在程序运行过程中, 需要记录一些信息到log中, 同时要尽量减少对主处理模块的影响,减少i|o的操作,所以CLog3中设计的思路为自己创建一个Thread,该Thread会获取一个队列中的讯息,当要写一个讯息的时候, 将要写的信息添加到队列中,并通知Thread获取队列中的资料,写入已经打开的文件中。

    因为在StartLog的时候,就已经将一个CFile对象打开了,所以减少了写是在Open的操作。

    而调用方只是将要写的log扔到队列中,然后就可以继续处理自己的事情了,不用等待log写完后在处理,减少了对主模块的影响。


    该开发环境是windows 2003 + vc.net 2005, 因为vc.net 2005中默认开启了Unicode 的模式,所以要写汉字到文件需要将CString转换成char * ,祥见: http://www.cnblogs.com/zhucl1006/archive/2008/01/02/1023380.html

    Clog3.h

    /* 一个写log的类
    时间 :2008-1-2
    版本 :1.0.0.0
    作者 :Karl.zhu
    */

    #pragma once

    #include 
    <afxmt.h>
    // CLog3 命令目标

    class CLog3
    {
    public:
        CLog3();
        
    void Init(CString FilePath,CString FileName);
        
    virtual ~CLog3();

    public :
        CString            m_FilePath;
        CString            m_FileName;
        DWORD                m_Fileday;
        CFile            m_File;

        HANDLE            m_processStopHandle,m_processSignalHandle,m_processThreadHandle;

        CStringList        m_messageQueue;
        CMutex            m_mutex;

        
    static void LogProcessorThread(LPVOID data);

        
    void QueueMessage(CString szLogEntry);
        
    void StartLog();
        
    void StopLog();
        
    void CrateLog(CString csFilePath,CString csFileName);



    }
    ;




    CLog3.cpp

    // 
    //
    /* 一个写log的类
    时间 :2008-1-2
    版本 :1.0.0.0
    作者 :Karl.zhu
    */

    #include 
    "stdafx.h"
    #include 
    "Log3Demo.h"
    #include 
    "Log3.h"

    #include 
    <process.h>

    // CLog3

    CLog3::CLog3()
    {
        

    }

    void CLog3::Init(CString FilePath,CString FileName)
    {
        m_FilePath 
    = FilePath;
        m_FileName 
    = FileName;
    }

    CLog3::
    ~CLog3()
    {

    }



    // CLog3 成员函数

    void CLog3::CrateLog(CString csFilePath,CString csFileName)
    {
        
    try
        
    {
            
    this->m_mutex.Lock();

            CFileFind find ;
            
    if (!find.FindFile(csFilePath))
            
    {
                CreateDirectory(csFilePath,NULL);
            }


            CString filename,fileexe;

            
    int Where = csFileName.ReverseFind(_T('.'));
            
    if (Where != -1)
            
    {
                filename 
    = csFileName.Left(Where);
                fileexe 
    = csFileName.Right(csFileName.GetLength() - Where - 1);
            }

            
    else
            
    {
                filename 
    = csFileName;
                fileexe 
    = "";
            }


            CTime now_time ;
            SYSTEMTIME tm;
            GetLocalTime(
    &tm);
            CString day;
            day.Format(_T(
    "_%02d"),tm.wDay);

            CString FileFullPath;
            FileFullPath.Format(_T(
    "%s\\%s%s.%s"),csFilePath,filename,day,fileexe);


            
    if (m_File.m_hFile != CFile::hFileNull)
            
    {
                m_File.Close();
                
            }

            
                
    if (!find.FindFile(FileFullPath,NULL))
                
    {
                    
    //没有找到
                    if (!m_File.Open(FileFullPath,CFile::modeCreate|CFile::modeReadWrite| CFile::shareDenyNone))
                    
    {
                        AfxMessageBox(_T(
    "Open File Error"));
                    }

                    
    this->m_Fileday = tm.wDay;
                }

                
    else
                
    {

                    
    //找到
                    WIN32_FIND_DATA FindFileData;
                    FindClose(FindFirstFile(FileFullPath,
    &FindFileData));
                    SYSTEMTIME csCreateTime;
                    FileTimeToSystemTime(
    &FindFileData.ftCreationTime,&csCreateTime);

                    
    if (tm.wDay == csCreateTime.wDay && tm.wMonth == csCreateTime.wMonth && tm.wYear == csCreateTime.wYear)
                    
    {
                        
    if(!m_File.Open(FileFullPath,CFile::modeReadWrite| CFile::shareDenyNone))
                        
    {
                            AfxMessageBox(_T(
    "Open Log Error"));
                        }

                        
    this->m_Fileday = tm.wDay;

                    }

                    
    else
                    
    {
                        
    if (!m_File.Open(FileFullPath,CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone))
                        
    {
                            AfxMessageBox(_T(
    "Open Log Error"));
                        }

                        
    else{
                            FILETIME  ft;
                            SystemTimeToFileTime(
    &tm,&ft);
                            SetFileTime(m_File.m_hFile,
    &ft,&ft,&ft);
                            
    this->m_Fileday = tm.wDay;

                        }

                    }

                    
    //memset(&FileInfo,0,sizeof(FILE_INFO));
                }

                
            
        }

        
    catch ()
        
    {
            DWORD lastError 
    = GetLastError();
            CString Err ;
            Err.Format(_T(
    "%d"),lastError);
            AfxMessageBox(Err);
        }

        
    this->m_mutex.Unlock();

    }




    void CLog3::StartLog()
    {
        
        CrateLog(m_FilePath,m_FileName);
        
    this->m_processStopHandle = CreateEvent(NULL,TRUE,FALSE,NULL);
        
    this->m_processSignalHandle = CreateEvent(NULL,TRUE,FALSE,NULL);

        m_processThreadHandle 
    = HANDLE(_beginthread(LogProcessorThread, 0this));
        
    if(m_processThreadHandle != LPVOID(-1))
        
    {
            AfxMessageBox(_T(
    "Log Thread OK"));

        }

        
    else
        
    {
            AfxMessageBox(_T(
    "Log Thread Faild"));
        }


        
    }

    void CLog3::StopLog()
    {
        SetEvent(
    this->m_processStopHandle);
    }

    void CLog3::LogProcessorThread(LPVOID data)
    {
        CLog3 
    *me = (CLog3 *) data;
        BOOL         bStop 
    = FALSE;
        DWORD         dwWritten;
        HANDLE         hHandleArray[
    2];

        ASSERT(me);

        hHandleArray[
    0= me->m_processStopHandle;
        hHandleArray[
    1= me->m_processSignalHandle;

        CString csData;

        
    while (bStop == FALSE)
        
    {
            
    switch (WaitForMultipleObjects(2, hHandleArray, FALSE, INFINITE))
            
    {
            
    case WAIT_OBJECT_0:
                bStop 
    = TRUE;
                
    break;

            
    case WAIT_OBJECT_0 + 1:
                
    //    Lock the queue to get the count and the next entry
                SYSTEMTIME tm1;
                GetLocalTime(
    &tm1);
                
    if (me->m_Fileday != tm1.wDay)
                
    {
                    me
    ->CrateLog(me->m_FilePath,me->m_FileName);
                }

                me
    ->m_mutex.Lock();
                
                
    while (me->m_messageQueue.GetCount())
                
    {
                    csData 
    = me->m_messageQueue.RemoveTail();
                    SYSTEMTIME tm;
                    GetLocalTime(
    &tm);
                    CString csFullData;
                    csFullData.Format(_T(
    "%02d:%02d:%02d[%03d]    %s"),tm.wHour,tm.wMinute,tm.wSecond,tm.wMilliseconds,csData);
                    
    //    Now unlock the queue while we write
                    me->m_mutex.Unlock();

                    
    //    Seek to the end of the file
                    me->m_File.SeekToEnd();
                    
                    DWORD leg 
    = WideCharToMultiByte(CP_OEMCP,NULL,csFullData,-1,NULL,0,NULL,FALSE);
                    CHAR strchar [
    5000];
                    WideCharToMultiByte(CP_OEMCP,NULL,csFullData,
    -1,strchar,leg,NULL,FALSE);
                    me
    ->m_File.Write(strchar,strlen(strchar));
                    

                    CHAR 
    * endline ="\r\n";
                    me
    ->m_File.Write(endline,strlen(endline));
                    me
    ->m_mutex.Lock();
                }


                
    //    Now unlock it again
                me->m_mutex.Unlock();

                
    //    Force output to disk
                me->m_File.Flush();
                ResetEvent(me
    ->m_processSignalHandle);
                
    break;
            }

        }


        me
    ->m_File.Close();

    AfxMessageBox(_T(
    "end File"));

    _endthread();
    }


    void CLog3::QueueMessage(CString szLogEntry)
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());

        ASSERT(szLogEntry);
        ASSERT(AfxIsValidString(szLogEntry));

        
    //    Lock the object for the addhead call
        
    //    (must be fast once we get the lock).
        m_mutex.Lock();
        m_messageQueue.AddHead(szLogEntry);
        m_mutex.Unlock();

        
    //    Now tell our processing thread there's 
        
    //    new stuff to write
        SetEvent(m_processSignalHandle);

    }


    这个算是我第一个vc的code,可能也存在什么不妥之处,读者们见笑了。

    Demo下载

  • 相关阅读:
    power desinger 学习笔记<五>
    power desinger 学习笔记<四>
    power desinger 学习笔记<八>
    kill session真的能杀掉进程吗
    转: Oracle AWR 报告 每天自动生成并发送邮箱
    Bootstrap 图片
    Bootstrap历练实例:禁用的按钮
    Bootstrap历练实例:点击激活的按钮
    Bootstrap历练实例:块级按钮
    Bootstrap历练实例:超小的按钮
  • 原文地址:https://www.cnblogs.com/zhucl1006/p/1023790.html
Copyright © 2011-2022 走看看