数据的读取和写入管理,可以通过列表和环型列表来实现,文本使用线性列表来实现数据的读取和写入操作。本文是C++的实现。
环型缓存区C代码实现,有一个C的liblcthw开源库。liblcthw的网址为https://github.com/zedshaw/liblcthw,用C代码实现了一些常用的数据结构,list,map,tree,字符串函数,ring buffer等。boost库里也有环形缓冲区的实现类circular_buffer
内存池类代码:
/*
描述: 内存池类
说明:
本类只支持同等大小的内存块
应当在所有Alloc的内存都Free以后再析构对象
*/
#ifndef _MemoryPool_h_
#define _MemoryPool_h_
#include <windows.h>
#include <LIST>
#define BLOCK_SIZE 1024
#define ONCE_BLOCK_COUNT 10
class MemoryPool
{
public:
MemoryPool(ULONG uBlockSize=BLOCK_SIZE);
virtual ~MemoryPool();
public:
//释放,用于代替析构,如果调用了它,不要调用析构,内存将在ReleaseMem时释放
void Release();
void* Alloc();
void Free(void* p);
public:
//初始化
static void Init();
//释放内存,程序结束时调用
static void ReleaseMem();
private:
ULONG m_uBlockSize;
std::list<void*> m_listFree;
CRITICAL_SECTION m_cs;
ULONG m_uBlockCnt;
ULONG m_uFreeCnt;
private:
static std::list<MemoryPool*> g_listPool;
static CRITICAL_SECTION g_cs;
};
#endif
#include "stdafx.h"
#include "MemoryPool.h"
std::list<MemoryPool*> MemoryPool::g_listPool;
CRITICAL_SECTION MemoryPool::g_cs;
MemoryPool::MemoryPool(ULONG uBlockSize)
{
m_uFreeCnt=0;
m_uBlockCnt=0;
m_uBlockSize=uBlockSize;
::InitializeCriticalSection(&m_cs);
}
MemoryPool::~MemoryPool()
{
BYTE* p;
::EnterCriticalSection(&m_cs);
std::list<void*>::iterator iter=m_listFree.begin();
std::list<void*>::iterator iterEnd=m_listFree.end();
while(iter!=iterEnd)
{
p=(BYTE*)(*iter);
iter++;
delete[] p;
}
m_listFree.clear();
::LeaveCriticalSection(&m_cs);
::DeleteCriticalSection(&m_cs);
}
//释放,用于代替析构,如果调用了它,不要调用析构,内存将在ReleaseMem时释放
void MemoryPool::Release()
{
//加入g_listPool
::EnterCriticalSection(&g_cs);
g_listPool.push_back(this);
::LeaveCriticalSection(&g_cs);
}
void* MemoryPool::Alloc()
{
void* p=NULL;
::EnterCriticalSection(&m_cs);
std::list<void*>::iterator iter=m_listFree.begin();
if(iter!=m_listFree.end())
{
p=*iter;
m_listFree.erase(iter);
}
if(p)
{
m_uFreeCnt--;
::LeaveCriticalSection(&m_cs);
return p;
}
//一次增加十个
BYTE* ap[ONCE_BLOCK_COUNT] = {0};
UINT i = 0;
for(i=0;i<ONCE_BLOCK_COUNT;i++)
{
ap[i]=new BYTE[m_uBlockSize];
}
for(i=1;i<ONCE_BLOCK_COUNT;i++)
{
m_listFree.push_back(ap[i]);
}
p=ap[0];
m_uBlockCnt+=ONCE_BLOCK_COUNT;
m_uFreeCnt+=(ONCE_BLOCK_COUNT-1);
::LeaveCriticalSection(&m_cs);
return p;
}
void MemoryPool::Free(void* p)
{
::EnterCriticalSection(&m_cs);
m_listFree.push_back(p);
m_uFreeCnt++;
::LeaveCriticalSection(&m_cs);
}
//初始化
void MemoryPool::Init()
{
::InitializeCriticalSection(&g_cs);
}
//释放内存,程序结束时调用
void MemoryPool::ReleaseMem()
{
MemoryPool* pThis;
::EnterCriticalSection(&g_cs);
std::list<MemoryPool*>::iterator iter=g_listPool.begin();
std::list<MemoryPool*>::iterator iterEnd=g_listPool.end();
while(iter!=iterEnd)
{
pThis=*iter;
iter++;
delete pThis;
}
g_listPool.clear();
::LeaveCriticalSection(&g_cs);
::DeleteCriticalSection(&g_cs);
}
线性缓存区代码:
//内存管理,线性缓存区操作类
#pragma once
#define BUFFER_MAX_SIZE 128*1024 //128K
class MemoryPool;
class CLineBuffer
{
public:
CLineBuffer(void);
virtual ~CLineBuffer(void);
public:
//-------------------------------------------------------------
// 功能:初始化
// 参数:缓冲区长度
// 返回:TRUE 成功,FALSE 失败
//-------------------------------------------------------------
BOOL Initialize(int nBufferLen,MemoryPool* pPool);
//-------------------------------------------------------------
// 功能:反初始化
// 参数:无
// 返回:无
//-------------------------------------------------------------
void Uninitialize();
//功能:复位
void Clear();
//功能:增加数据
int AddData(char *pBuffer,int nLen);
//功能:增加数据(返回增加数据的指针)
int AddData(char *pBuffer,int nLen,char **pNewBuffer);
//功能:删除数据
int DeleteData(int nLen,int nStartPos=-1);
//功能:读取数据(提前预读取)
int PrepareReadData(char **pBuffer,int nLen);
//功能:读取数据
int ReadData(char **pBuffer,int nLen);
//功能:获取空间总大小
int GetSpaceTotalLength();
//功能:获取剩余空间大小
int GetRemainSpaceLength();
//功能:获取剩余写空间大小(左边)
int GetLeftRemainSpaceLength();
//功能:获取剩余写空间大小(右边)
int GetRightRemainSpaceLength();
//功能:获取实际数据大小
int GetActualDataLength();
//功能:获取读位置
int GetReadPos();
//功能:设置读位置
void SetReadPos(int nNewReadPos);
//功能:获取写位置
int GetWritePos();
//功能:压缩数据
int CompactData();
private:
MemoryPool* m_pMemPool; //内存池对象
char *m_pBufferData; //缓冲区数据
int m_nBufferDataLen; //缓冲区大小
int m_nBufferReadPos; //读位置
int m_nBufferWritePos; //写位置
int m_nBufferEmptySize; //剩余大小
//临界池保护
CRITICAL_SECTION m_critial;
};
#include "StdAfx.h"
#include "LineBuffer.h"
#include <windows.h>
#include "MemoryPool.h"
CLineBuffer::CLineBuffer(void)
{
m_pMemPool = NULL;
m_pBufferData = NULL;
m_nBufferDataLen = 0;
m_nBufferReadPos = 0;
m_nBufferWritePos = 0;
m_nBufferEmptySize = 0;
InitializeCriticalSection(&m_critial);
}
CLineBuffer::~CLineBuffer(void)
{
if(m_pBufferData != NULL)
{
delete []m_pBufferData;
m_pBufferData = NULL;
}
DeleteCriticalSection(&m_critial);
}
//-------------------------------------------------------------
// 功能:初始化
// 参数:缓冲区长度
// 返回:TRUE 成功,FALSE 失败
//-------------------------------------------------------------
BOOL CLineBuffer::Initialize(int nBufferLen,MemoryPool* pPool)
{
if(m_nBufferDataLen>0 || nBufferLen<=0)
return FALSE;
m_pMemPool = pPool;
if(m_pMemPool)
{
m_pBufferData=(char*)m_pMemPool->Alloc();
}
else
{
m_pBufferData=new char[nBufferLen];
}
m_nBufferDataLen = nBufferLen;
m_nBufferEmptySize = m_nBufferDataLen;
return TRUE;
}
//-------------------------------------------------------------
// 功能:反初始化
// 参数:无
// 返回:无
//-------------------------------------------------------------
void CLineBuffer::Uninitialize()
{
if(m_pBufferData)
{
if(m_pMemPool)
m_pMemPool->Free(m_pBufferData);
else
delete[] m_pBufferData;
m_pBufferData = NULL;
}
m_nBufferDataLen = 0;
m_nBufferEmptySize = 0;
}
//功能:复位
void CLineBuffer::Clear()
{
EnterCriticalSection(&m_critial);
m_nBufferReadPos = 0;
m_nBufferWritePos = 0;
m_nBufferEmptySize = m_nBufferDataLen;
LeaveCriticalSection(&m_critial);
}
/*
功能:增加数据
参数:pBuffer,表示数据;nLen,表示数据长度
返回值:int类型 0,表示正确;1,表示参数错误;2,表示数据太大
*/
int CLineBuffer::AddData(char *pBuffer,int nLen)
{
EnterCriticalSection(&m_critial);
//参数错误
if(m_pBufferData == NULL)
{
LeaveCriticalSection(&m_critial);
return 1;
}
if((m_nBufferWritePos%m_nBufferDataLen - m_nBufferReadPos) == 0)
{
m_nBufferReadPos = m_nBufferWritePos = 0;
m_nBufferEmptySize = m_nBufferDataLen;
}
//数据太大
if((m_nBufferDataLen - m_nBufferWritePos) <= nLen)
{
LeaveCriticalSection(&m_critial);
return 2;//超过已有缓冲区大小
}
memcpy(m_pBufferData+m_nBufferWritePos,pBuffer,nLen);
m_nBufferWritePos +=nLen;
m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
LeaveCriticalSection(&m_critial);
return 0;
}
//功能:增加数据(返回增加数据的指针)
int CLineBuffer::AddData(char *pBuffer,int nLen,char **pNewBuffer)
{
EnterCriticalSection(&m_critial);
//参数错误
if(m_pBufferData == NULL)
{
LeaveCriticalSection(&m_critial);
return 1;
}
if((m_nBufferWritePos%m_nBufferDataLen - m_nBufferReadPos) == 0)
{
m_nBufferReadPos = m_nBufferWritePos = 0;
m_nBufferEmptySize = m_nBufferDataLen;
}
//数据太大
if((m_nBufferDataLen - m_nBufferWritePos) <= nLen)
{
LeaveCriticalSection(&m_critial);
return 2;//超过已有缓冲区大小
}
memcpy(m_pBufferData+m_nBufferWritePos,pBuffer,nLen);
*pNewBuffer = m_pBufferData+m_nBufferWritePos; //设置新数据位置
m_nBufferWritePos +=nLen;
m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
LeaveCriticalSection(&m_critial);
return 0;
}
/*
功能:删除数据
参数:nLen,表示需要删除数据的长度;nStartPos,表示开始位置(-1,表示从当前读位置开始)
返回值:int类型 0,表示成功;-1,表示要删除的数据超过了已有数据;-2,表示参数错误
*/
int CLineBuffer::DeleteData(int nLen,int nStartPos)
{
EnterCriticalSection(&m_critial);
if((nStartPos < 0 && nStartPos !=-1) || nLen <= 0)
{
//参数错误
LeaveCriticalSection(&m_critial);
return -2;
}
int nStartPosTmp = nStartPos;
if(-1 == nStartPos)
{
nStartPosTmp = m_nBufferReadPos;
}
if((nStartPosTmp + nLen) > m_nBufferWritePos)
{
//要删除的数据超过了已有数据
LeaveCriticalSection(&m_critial);
return -1;
}
m_nBufferReadPos = nStartPosTmp + nLen;
m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
LeaveCriticalSection(&m_critial);
return 0;
}
//功能:读取数据(提前读取)
int CLineBuffer::PrepareReadData(char **pBuffer,int nLen)
{
int nActualReadSize = 0;
EnterCriticalSection(&m_critial);
int nDataLength = m_nBufferWritePos - m_nBufferReadPos;
if(nDataLength > 0)
{
if(nDataLength >= nLen)
{
*pBuffer = m_pBufferData+m_nBufferReadPos;
nActualReadSize = nLen;
}
else
{
*pBuffer = m_pBufferData+m_nBufferReadPos;
nActualReadSize = nDataLength;
}
}
LeaveCriticalSection(&m_critial);
return nActualReadSize;
}
//功能:读取数据
int CLineBuffer::ReadData(char **pBuffer,int nLen)
{
int nActualReadSize = 0;
EnterCriticalSection(&m_critial);
int nDataLength = m_nBufferWritePos - m_nBufferReadPos;
if(nDataLength > 0)
{
if(nDataLength >= nLen)
{
*pBuffer = m_pBufferData+m_nBufferReadPos;
nActualReadSize = nLen;
m_nBufferReadPos = m_nBufferReadPos + nLen;
}
else
{
*pBuffer = m_pBufferData+m_nBufferReadPos+nDataLength;
nActualReadSize = nDataLength;
m_nBufferReadPos = m_nBufferReadPos + nDataLength;
}
m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
}
if(m_nBufferWritePos == m_nBufferReadPos)
{
m_nBufferReadPos = m_nBufferWritePos = 0;
m_nBufferEmptySize = m_nBufferDataLen;
}
LeaveCriticalSection(&m_critial);
return nActualReadSize;
}
//功能:压缩数据
int CLineBuffer::CompactData()
{
EnterCriticalSection(&m_critial);
if(m_pBufferData != NULL)
{
int nActualSize = m_nBufferWritePos - m_nBufferReadPos;
for(int i=0;i<nActualSize;i++)
{
m_pBufferData[i] = m_pBufferData[i+m_nBufferReadPos];
}
m_nBufferReadPos = 0;
m_nBufferWritePos = nActualSize;
m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
}
LeaveCriticalSection(&m_critial);
return 0;
}
//功能:获取空间总大小
int CLineBuffer::GetSpaceTotalLength()
{
return m_nBufferDataLen;
}
//功能:获取剩余空间大小
int CLineBuffer::GetRemainSpaceLength()
{
return m_nBufferEmptySize;
}
//功能:获取剩余写空间大小(左边)
int CLineBuffer::GetLeftRemainSpaceLength()
{
return m_nBufferReadPos;
}
//功能:获取剩余写空间大小(右边)
int CLineBuffer::GetRightRemainSpaceLength()
{
return m_nBufferDataLen - m_nBufferWritePos;
}
//功能:获取实际数据大小
int CLineBuffer::GetActualDataLength()
{
int nActualDataLength = 0;
nActualDataLength = m_nBufferWritePos - m_nBufferReadPos;
return nActualDataLength;
}
//功能:获取读位置
int CLineBuffer::GetReadPos()
{
return m_nBufferReadPos;
}
//功能:设置读位置
void CLineBuffer::SetReadPos(int nNewReadPos)
{
m_nBufferReadPos = nNewReadPos;
}
//功能:获取写位置
int CLineBuffer::GetWritePos()
{
return m_nBufferWritePos;
}