最近在项目中要用到Netty框架,期间碰到了很多ChannelBuffer的使用,但是了解不多,被各种readable、readableBytes……搞的晕晕的,所以仔细研究了一下这个ChannelBuffer的结构,算是做个笔记吧。
首先上个简单的结构图吧:
+-------------------+------------------+------------------+ | discardable bytes | readable bytes | writable bytes | | | (CONTENT) | | +-------------------+------------------+------------------+ | | | | 0 <= readerIndex <= writerIndex <= capacity
说明:实际上,ChannelBuffer跟一个普通的byte array没有什么差别,只是包装成了面向对象的了,而且加上了不少的属性和方法。
ChannelBuffer有两个属性,readerIndex和writerIndex两个指针来分别控制读写;
一个ChannelBuffer被分成三个区域:discardable、readable和writeable,分别表示已经读过的内容、实际还剩下的内容、Buffer剩余的空间也就是可以写的缓冲区大小;
read和skip操作:会从readerIndex位置读取或skip指定数量的bytes,readerIndex+=size(bytes),如果读区的下标越界,抛出IndexOutOfBoundsException异常
;
write操作:从writerIndex位置写入buffer指定size的bytes,writeIndex+=size(bytes),如果空间不够,抛出IndexOutOfBoundsException
异常
几个常用的方法:
readable() 返回 boolean (writerIndex-readerIndex)
readableBytes() 返回int (writerIndex-readerIndex)
writeableBytes() 返回int (capacity-writerIndex)
关于discardable bytes,有一个释放discardable区域的方法:discardReadBytes()
+-------------------+------------------+------------------+ | discardable bytes | readable bytes | writable bytes | +-------------------+------------------+------------------+ | | | | 0 <= readerIndex <= writerIndex <= capacity 调用 discardReadBytes()方法后 +------------------+--------------------------------------+ | readable bytes | writable bytes (got more space) | +------------------+--------------------------------------+ | | | readerIndex (0) <= writerIndex (decreased) <= capacity
Buffer.clear()
调用clear()之前
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
调用clear()之后
+---------------------------------------------------------+ | writable bytes (got more space) | +---------------------------------------------------------+ | | 0 = readerIndex = writerIndex <= capacity
Mark和Reset,可以和InputStream一样使用,但是有两个指针;
markReaderIndex()
markWriterIndex()
resetReaderIndex()
resetWriterIndex()
duplicate(), slice() or slice(int, int)和copy()的区别;
有时候需要对buffer建一份拷贝,在拷贝上进行读写,这里有两种方法;
duplicate(), slice()
or slice(int, int):拷贝和源
共享buffer的数据区域,但是拷贝有自己的readerIndex和writerIndex以及markIndex,实际上只是拷贝了控制指针;
copy():完整的拷贝,不解释