MINA ByteBuffer熟悉
前不久,一个客户使用MINA架构服务器,在与客户端通信时,出现了问题。表现的现象是第一次通讯可以,从第二次通讯开始就出错。那时候,我还没有接触过MINA,只好用二分法打印中间数据,最后花了两个多小时,找到了错误的原因,就是因为对ByteBuffer不熟悉,在使用ByteBuffer的limit方法时,产生了一个字节的错位。
?
ByteBuffer是MINA中最常用的类之一,搞清楚它的原理是非常有必要的。
?
ByteBuffer是一个线性的字节空间,相当于字节数组;在初始化时,要给它分配一个大小。但是实际分配的大小,是有规则的,一般为128的倍数。比如,传入的值为100,则分配128;传入200,则分配256;传入300,则分配512。
?
ByteBuffer有五个重要的属性;position、limit、mark、remaining和capacity;
?
新分配的空间;position为0;limit和remaining等于capacity;mark为-1;
?
使用ByteBuffer的clear方法后,ByteBuffer的状态和新分配的状态一样。
?
怎么向ByteBuffer中添加数据?
?
使用put方法,position将发生改变;如果put的数据超过了limit和capacity的限制,将会抛出异常:BufferOverflowException;
?
在使用put方法后,remaining反映了ByteBuffer中有效数据情况。
?
如果将ByteBuffer的AutoExpand设置为true,当分配的capacity不够时,capacity将会自动扩张。扩张的策略与分配空间的策略相同。
?
怎么从ByteBuffer中读取数据?
?
使用get方法;需要注意的是,position记录的是当前的位置;对于get和put有着不同的含义;get需要的position是数据的开头;而put的position表示的数据的结尾。
所以,在写入数据和读取数据之间要用flip方法;
?
flip方法用limit记录数据的尾,并将position清0表示数据的头。
?
有的时候,需要读取当前位置的position之前的数据,这需要通过mark和reset实现。
?
如何移动ByteBuffer中某一块的数据?
?
先建一个ByteBuffer,把需要移动的数据块拷贝到ByteBuffer中;再将当前ByteBuffer清空;最后,将新的ByteBuffer的数据拷贝回来。