在通讯部分为了防止出现数据覆盖的情况,经常使用循环缓冲区来处理数据。下面是用C#实现的简单循环缓冲区类,希望能够帮助需要的同学。
//通讯缓冲结构类
internal class CommBuffer
{
public uint capacity; //缓冲区大小
public int readPtr; //读指针
public int writePtr; //写指针
public byte[] pBuf; //缓冲区
//构造函数
public CommBuffer(uint capacity)
{
this.capacity = capacity;
this.readPtr = 0;
this.writePtr = 0;
this.pBuf = new byte[capacity];
}
//从缓冲区中读取数据到byte数组
public int Read(byte[] buff, int size)
{
int readSize;
for (readSize = 0; readSize < size; readSize++)
{
if (IsEmpty())
break;
buff[readSize] = pBuf[readPtr++];
if (readPtr >= capacity)
readPtr = 0;
}
return readSize;
}
//将byte数组写入缓冲区
public int Write(byte[] buff, int size)
{
int writeSize, wp;
for (writeSize = 0; writeSize < size; writeSize++)
{
wp = writePtr + 1;
if (wp >= capacity)
wp = 0;
if (wp == readPtr)
break;
pBuf[writePtr] = buff[writeSize];
writePtr = wp;
}
return writeSize;
}
//拷贝buffer缓冲区数据到本缓冲区内,会引起拷贝源有效数据为空
public int Copy(CommBuffer buffer, int len)
{
if (len == 0)
return 0;
byte[] data = new byte[len];
len = buffer.Read(data, len);
return this.Write(data, len);
}
//拷贝本缓冲区中的数据到buffer中,会引起拷贝源有效数据为空
public int CopyTo(CommBuffer buffer)
{
int dataLen = this.DataLength();
if (dataLen == 0)
return 0;
byte[] data = new byte[dataLen];
dataLen = this.Read(data, dataLen);
return buffer.Write(data, dataLen);
}
//索引器实现
public byte this[int index]
{
get
{
if (index >= DataLength())
return 0;
int rp = readPtr + index;
if (rp >= capacity)
rp = rp-(int)capacity;
return pBuf[rp];
}
}
//忽略len长度的数据
public void Skip(int len)
{
while (len-- > 0) {
if (readPtr == writePtr)
break;
readPtr++;
if (readPtr >= capacity)
readPtr = 0;
}
}
//判断是否有数据
public bool IsEmpty()
{
return writePtr == readPtr;
}
//获取有效数据长度
public int DataLength()
{
int len = writePtr-readPtr;
if (len < 0)
len = len + (int)capacity;
return len;
}
//清空缓冲区
public void Clear()
{
writePtr = readPtr = 0;
}
//缓冲区整理,将数据移动到0位置,方便后续数据的处理
public void Neaten()
{
uint i, j;
if (readPtr == 0)
{
return; //读指针已经为0
}
if (readPtr >= writePtr)
{
readPtr = writePtr = 0;
return;
}
if (writePtr >= capacity)
{
readPtr = 0;
writePtr = 0;
return;
}
i = 0;
j = (uint)readPtr;
while (j < writePtr)
{
pBuf[i++] = pBuf[j++];
}
readPtr = 0;
writePtr = (int)i;
}
//显示缓存数据
public override string ToString()
{
int dataLen = this.DataLength();
string str = string.Format("数据长度{0}: ", this.DataLength());
for (int i = 0; i < dataLen; i++)
{
str += string.Format("{0:X} ",this[i]);
}
return str;
}
}