C# 动态缓冲区的实现

在网络编程的开发环境当中经常会使用缓冲区来进行数据的接收与发送,但是当我们需要发一段连续的数据的时候,使用

1
byte[] _buffer= new byte[lenght];

显然很死板,我们需要一个更加“智能”的缓冲区来管理这些数据。 ok,我们可以编写一个动态缓冲区管理器,它在内部维护一个byte[]类型的缓冲区,还有一个数据指针,以及已使用的字节空间的计数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class DynamicBufferManager
{
    public int DataCount {get;private set;}
    public int DataPointer {get;private set;}
    public byte[] Buffer {get;private set;}

    public DynamicBufferManager(int size)
    {
        DataCount = 0;
        DataPointer = 0;
        BUffer = new byte[size];
    }
}

我们的动态缓冲管理器主要就是由一个内部缓冲区还有一个数据指针已用数据计数器来构成的。我们的主要思路是,我们的动态缓冲区可以随时设置新的大小,可以清除指定大小/全部的数据。当然我们也可以向缓冲区内写入/读取我们所需要的数据。

下面我们来实现大小与清除数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class DynamicBufferManager
{
    public void SetBufferSize(int newSize)
    {
        if(newSize > Buffer.Lenght) // 如果新缓冲区大小大于内部缓冲区大小则扩容
        {
            byte[] _tmpBuffer = new byte[newSize];
            Array.Copy(Buffer,_tmpBuffer,DataCount);
            Buffer = _tmpBuffer;
        }
    }

    public void Clean()
    {
        DataCount = 0;
    }

    public void Clean(int count)
    {
        if(count > DataCount)
        {
            DataCount = 0;
        }else // 所有数据前移count位置
        {
            for(int i = 0;i < DataCount - count;i++)
            {
                Buffer[i] = Buffer[i + count];
            }
            DataCount-=count;
        }
    }
}

好了,现在让我们来开始向内部缓冲区写入数据吧~

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class DynamicBufferManager
{
    // 获得可用字节数
    public int ReserveCount
    {
        get
        {
            return Buffer.Lenght - DataCount;
        }
    }

    public void WriteBytes(byte[] buffer,int offset,int lenght)
    {
        if(ReserveCount > lenght) // 如果内部缓冲区能够存放的话
        {
            Array.Copy(buffer,offset,Buffer,DataCount,lenght);
            DataCount+=lenght;
        }else // 扩展缓冲区
        {
            int _newSize = Buffer.Lenght + lenght - ReserveCount;
            byte[] _tmpBytes = new byte[_newSize];
            Array.Copy(Buffer,_tmpBytes,DataCount);
            Array.Copy(buffer,offset,_tmpBytes,DataCount,lenght);
            Buffer = _tmpBytes;
            DataCount+=lenght;
        }
    }

    public void WriteBytes(byte[] buffer)
    {
        WriteBytes(buffer,0,buffer.Lenght);
    }
}

下面我们来演示从读取/写入整形的一个方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class DynamicBufferManager
{
    public void WriteInt32(bool IsNetBytes,int value)
    {
        if(IsNetBytes) value = Systsem.Net.IPAdress.HostToNetworkOrder(value);
        WriteBytes(BitConverter.GetBytes(value));
    }

    public int ReadToInt32(bool IsNetBytes)
    {
        int _value = BitConvert.ToInt32(Buffer,DataPointer);
        DataPointer+=4;
        if(IsNetBytes) _value = System.Net.IPAdress.NetworkToHostOrder(_value);
        return _value;
    }
}
Built with Hugo
主题 StackJimmy 设计