可以读写二进制文件的类(支持加密,不支持多线程)

头文件TeaBinLog.h

/********************************************************************
	purpose:	写二进制形式的日志文件,不支持多线程操作
*********************************************************************/
#pragma once

const UINT32 MAX_LOG_LEN = 1024;//单条日志的最大长度不能超过这个值,否则读/写都会失败

enum E_TEABINLOG_ERR
{
    E_TEABINLOG_ERR_SUCCESS,//成功
    E_TEABINLOG_ERR_OUTOF_RANGE,//日志长度过长
    E_TEABINLOG_ERR_ACCESS_FAIL,//文件无法访问
    E_TEABINLOG_ERR_READ_FAIL,//读取单条日志的过程中发生异常
};

//读取时的回调函数
//返回非0表示停止读取数据
typedef int (__stdcall *ReadCallFunction)(const UINT32 uLogId, BYTE *pBuf, UINT32 uBufLen);

class TeaBinLog
{
public:
    TeaBinLog(void);
    ~TeaBinLog(void);
   
    void SetFileName(TCHAR* lpszFileName);

    int WriteLog(const UINT32 uLogId, const BYTE* const pBuf, const UINT32 uBufLen, UINT8 bEncrypt = 0);
    int ReadLog(ReadCallFunction fn);

    /*************************************************************************
    Author  :      HuangYongbo [2013-10-23 15:29]
    Function:      加密/解密,加密或者解密之后,缓冲区的长度应该保持不变  
    Parameters:    
    Return Value:  If success return 0, otherwise return nonzero.
    *************************************************************************/
    virtual int Encrypt(const BYTE* const pBuf, const UINT32 uBufLen, 
        BYTE *pBufRet, BOOL bEncrypt);


private:
    CFile m_file;
    TCHAR m_szFileName[MAX_PATH];
    bool m_bReadLoop;
};

 

 

源文件TeaBinLog.cpp

#include "StdAfx.h"
#include "TeaBinLog.h"

TeaBinLog::TeaBinLog(void):
m_bReadLoop(false)
{
    ZeroMemory(m_szFileName, MAX_PATH);
}

TeaBinLog::~TeaBinLog(void)
{
}

int TeaBinLog::WriteLog( const UINT32 uLogId, const BYTE* const pBuf, const UINT32 uBufLen , UINT8 bEncrypt/* = 0*/)
{
    if (uBufLen > MAX_LOG_LEN)
    {
        return E_TEABINLOG_ERR_OUTOF_RANGE;
    }

    if (FALSE == m_file.Open(m_szFileName, CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate))
    {
        AfxMessageBox("打开文件失败。");
        return E_TEABINLOG_ERR_ACCESS_FAIL;
    }


    int iFileLength = (int)m_file.GetLength();
    m_file.SeekToEnd();

    m_file.Write(&bEncrypt, sizeof(bEncrypt));
    m_file.Write(&uLogId, sizeof(uLogId));
    m_file.Write(&uBufLen, sizeof(uBufLen));
    
    if ( 1 == bEncrypt)
    {
        //加密
        BYTE *pTempBuf = new BYTE[uBufLen];
        Encrypt(pBuf,uBufLen, pTempBuf, TRUE);
        m_file.Write(pTempBuf, uBufLen);
        delete []pTempBuf;
    }
    else
    {
        m_file.Write(pBuf, uBufLen);
    }
    m_file.Close();
    return 0;   

}


int TeaBinLog::ReadLog( ReadCallFunction fn )
{
    if (FALSE == m_file.Open(m_szFileName, CFile::modeRead))
    {
        AfxMessageBox("打开文件失败。");
        return E_TEABINLOG_ERR_ACCESS_FAIL;
    }
    m_file.SeekToBegin();

    int nRet(0);
    UINT32 uLogId(0);
    UINT32 uLogLen(0);
    UINT32 uReadRet(0);
    UINT8 bEncrypt(0);
    BYTE pBuf[MAX_LOG_LEN] = {};
    m_bReadLoop = true;
    while (m_bReadLoop)
    {
        //encrypt information
        uReadRet = m_file.Read(&bEncrypt, sizeof(bEncrypt));
        if (uReadRet < sizeof(bEncrypt))
        {
            nRet = E_TEABINLOG_ERR_READ_FAIL;
            break;
        }

        //log id
        uReadRet = m_file.Read(&uLogId, sizeof(uLogId));
        if (uReadRet < sizeof(uLogId))
        {
            nRet = E_TEABINLOG_ERR_READ_FAIL;
            break;
        }

        //log length
        uReadRet = m_file.Read(&uLogLen, sizeof(uLogLen));
        if (uReadRet < sizeof(uLogLen))
        {
            nRet = E_TEABINLOG_ERR_READ_FAIL;
            break;
        }
 
        //log information
        uReadRet = m_file.Read(pBuf, uLogLen);
        if (uReadRet < uLogLen)
        {
            nRet = E_TEABINLOG_ERR_READ_FAIL;
            break;
        }

        if ( 1 == bEncrypt)
        {
            //解密
            BYTE *pTempBuf = new BYTE[uLogLen];
            Encrypt(pBuf,uLogLen, pTempBuf, FALSE);
            if(0 != fn(uLogId, pTempBuf, uLogLen))
            {
                m_bReadLoop = false;
            }
            delete []pTempBuf;
        }
        else
        {       
            if (0 != fn(uLogId, pBuf, uLogLen))
            {
                m_bReadLoop =false;
            }
        }
    }
    m_file.Close();
    return nRet;   
}

void TeaBinLog::SetFileName( TCHAR* lpszFileName )
{
    _tcscpy_s(m_szFileName, MAX_PATH*sizeof(TCHAR), lpszFileName);
}


int TeaBinLog::Encrypt( const BYTE* const pBuf, const UINT32 uBufLen, 
                       BYTE *pBufRet,BOOL bEncrypt)
{
    if (TRUE == bEncrypt)
    {
        //加密
        for (UINT32 i=0; i<uBufLen; i++)
        {
            if (0xff == pBuf[i])
            {
                pBufRet[i] = 0;
            } 
            else
            {
                pBufRet[i] = pBuf[i] + 1;
            }
        }
        //memcpy(pBufRet, pBuf, uBufLen);
    }
    else
    {
        //解密
        for (UINT32 i=0; i<uBufLen; i++)
        {
            if (pBuf[i] == 0)
            {
                pBufRet[i] = 0xff;
            }
            else
            {
                pBufRet[i] = pBuf[i] - 1;
            }
        }
        //memcpy(pBufRet, pBuf, uBufLen);
    }
    return 0;
}


 

测试文件

#include "StdAfx.h"
#include "MainLog.h"
#include "TeaBinLog.h"

TeaBinLog g_log;
const UINT32 LOG_HEADER_LEN = 64;//日志头中,留100个字节去存储信息

struct LOG_HEADER 
{
    UINT32 uVer;
};

struct DATA1 
{
    int n;
};

const UINT32 DATA2_LEN = 0x10;
struct DATA2 
{
    char szInfo[DATA2_LEN];
};

enum E_LOG_ID
{
    ELOG_HEADER,
    ELOG_DATA1,
    ELOG_DATA2,
};


int  __stdcall ReadFunction(const UINT32 uLogId, BYTE *pBuf, UINT32 uBufLen)
{
    DATA1 *pData1(NULL);
    DATA2 *pData2(NULL);
    LOG_HEADER* pData(NULL);
    int nRet(0);
    switch (uLogId)
    {
    default:
        break;
    case ELOG_DATA1:
        {
            ASSERT(uBufLen == sizeof(DATA1));
            pData1 = (DATA1*)pBuf;
        }
        break;
    case ELOG_DATA2:
        {
            ASSERT(uBufLen == sizeof(DATA2));
            pData2 = (DATA2*)pBuf;
        }
        break;
    case ELOG_HEADER:
        {
            ASSERT(uBufLen == LOG_HEADER_LEN);
            pData = (LOG_HEADER*)pBuf;
        }
        break;
    }

    return 0;
}

int ReadLog()
{
    g_log.SetFileName(_T("d:\\aa.txt"));
    g_log.ReadLog(ReadFunction);
    return 0;
}


int WriteLog()
{ 
    g_log.SetFileName(_T("d:\\aa.txt"));

    //写文件头
    BYTE HeadBuf[LOG_HEADER_LEN] = {};
    LOG_HEADER *pHeader = (LOG_HEADER*)HeadBuf;
    pHeader->uVer = 2;
    g_log.WriteLog(ELOG_HEADER, HeadBuf, LOG_HEADER_LEN, 0);

    //写其它数据
    DATA1 data1;
    ZeroMemory(&data1, sizeof(data1));
    data1.n = 5;
    g_log.WriteLog(ELOG_DATA1, (BYTE*)&data1, sizeof(data1),1);

    DATA2 data2;
    ZeroMemory(&data2, sizeof(data2));
    _tcscpy_s(data2.szInfo, DATA2_LEN, _T("中国"));
    g_log.WriteLog(ELOG_DATA2, (BYTE*)&data2, sizeof(data2), 0);
    return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值