ByteBuf维护两个不同的指针,readerIndex(读索引)和writerIndex(写索引) 顾名思义一个指针用于读,一个指针用于写.它们之间有如下关系:
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
可丢弃字节 可读字节(CONTENT) 可写字节
已被读 未被读 剩余可写字节空间
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
一些常用方法:
返回值 | 方法和描述 |
boolean | isReadable() 至少有一个字节可读则返回true |
boolean | isWritable() 至少有一个字节能被写入则返回true |
int | readableBytes() 返回可被读取的字节数 |
int | writableBytes() 返回可被写入的字节数 |
int | capacity() 返回此ByteBuf的容量,ByteBuf如果到达此容量它会尝试扩容到maxCapacity() |
int | maxCapacity() 得到ByteBuf可以容纳的最大字节数 |
boolean | hasArray() 如果ByteBuf由一个字节数组支撑,返回true |
byte[] | array() 满足hasArray()==true 之后可有调用此方法得到此ByteBuf的支撑数组 如果hasArray()==false 调用它会抛出UnsupportedOperationException |
String | toString() toString(Charset charset) toString (int index, int length, Charset charset)
将该缓冲区的子区域解码为带有指定字符集的字符串。 该方法不会修改该缓冲区的readerIndex或writerIndex。 |
可丢弃字节可以调用 discardReadBytes() 方法回收空间(可丢弃空间会变成可写状态), 不要频繁的调用这个方法,这容易造成内存复制.discardReadBytes()
调用 discardReadBytes() 后 readindex = 0; writeindex -= 回收字节数.
+------------------+--------------------------------------+
| readable bytes | writable bytes (获得更多空间) |
可读字节 可写字节(刚扩展)
+------------------+--------------------------------------+
| | |
readerIndex (0) <= writerIndex (已减少) <= capacity
可读字节存储了实际数据:可以用readableBytes() 获取可读字节数:
int | readableBytes() 返回可读字节数(writerIndex-readerIndex). |
可以用各种read方法[readerIndex会按照所读字节数增加]获取ByteBuf内byte数组对应(readerIndex~readerIndex+数据长度)这段位置的数据附各种read方法 不清楚可以去上面我给的地址去查看,特别说明一下 Medium 是占三个byte(24位)的整数!
int | readMedium() 返回索引处readindex~readindex+3的24位(3byte)的中等int值, 同时readindex+=3. |
short |
readShort()
返回索引处 readindex~ readindex+2的16位(2byte)的短整数值,
同时readindex+=2.
|
ByteBuf | readBytes(ByteBuf dst, int dstIndex, int length) 当前ByteBuf的数据读取到目标ByteBuf中,读取长度为length 目标ByteBuf的起始索引为dstIndex,不是writerIndex.操作完成之后 当前ByteBuf的readIndex+=length dstIndex<0或dstIndex+length>目标ByteBuf的capacity抛出 下标越界异常. |
get()方法类操作,获取索引处对应的值,它的功能很简单我就不过多赘述:
可写字节是指一段未定义内容的,可以写入数据的内存区域,可以writableBytes()获取这段内存区域的长度(可写字节数).
一些write():
ByteBuf | writeByte(int value) 在当前writerIndex处写入一个boolean,同时writerIndex+=1. |
ByteBuf | writeBytes( ByteBuf | byte[] src, int srcIndex, int length) 从当前writerIndex开始,传输来指定源(ByteBuf或byte[])的 数据.如果提供了srcIndex和length,则从srcIndex开始读取 并且写入长度为length的字节.writerIndex+=lenght. |
ByteBuf | writeLong(long value) 在writerIndex处写入一个long值,同时writerIndex+=8. |
其它的write方法同理:
既然有有get方法那么也有set方法 set()操作就是设定指定索引的值,如:
ByteBuf | setLong(int index, long value) 设定索引(index~index+8)处的long值 |
和InputStream类似,ByteBuf可以调用markReaderIndex(),markWriterIndex(),resetReaderIndex(),resetWriterIndex()来标记和重置readindex,writeIndex.同时也可以通过 readerIndex(intreaderIndex),writerIndex(int writerIndex)来将索引移动到指定位置,注意移动任何一个无法到达的索引都会造成IndexOutOfBoundException.
可以通过调用clear()方法将readindex,writerIndex都设置为0:
调用 clear()之前
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
可回收区 可读 可写
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
调用 clear()之后
+---------------------------------------------------------+
| writable bytes (got more space) |
+---------------------------------------------------------+
| |
0 = readerIndex = writerIndex <= capacity
indexOf(int, int, byte),和bytesBefore(int, int, byte) 方法
.bytesBefore(int, int, byte)方法对处理null终止的字符串时特别有用.对于较复杂的查找,可以通过
未完待续....