ByteBuf是Netty的Server与Client之间通讯的数据传输载体.他提供了一个byte数组(byte[])的抽象视图数组
咱们推荐经过一个Unpooled的帮助方法来建立新的buffer而不是经过调用独立的构造器来建立dom
就像普通的原声字节数组同样, ByteBuf使用零基坐标(zero-based indexing). 这表示第一个字节的坐标老是0, 最后一个字节的坐标老是capacity - 1.例如, 要遍历buffer的全部字节,你能够按下面这样作:spa
ByteBuf buffer = ...; for (int i = 0; i < buffer.capacity(); i ++) { byte b = buffer.getByte(i); System.out.println((char) b); }
ByteBuf提供了两个指针变量来支持顺序读写操做 - readerIndex用来支持读操做, writerIndex用来支持写操做.下面的表格显示了一个buffer是如何经过两个指针分段为三部分的3d
这个段是真实数据储存的地方.任何名字以start或skip开始的操做都会增长当前readerIndex他读过的字节数.若是读操做的参数也是一个ByteBuf, 而且没有指定目的地坐标, 那么指定ByteBuf的writerIndex也会一块儿增长指针
若是buf没有足够的内容可供读取,会抛出IndexOutOfBoundsException. 最新分配的buffer, buffer的包装类和副本的readerIndex默认值都是0code
// Iterates the readable bytes of a buffer. ByteBuf buffer = ...; while (buffer.readable()) { System.out.println(buffer.readByte()); }
这个段是一个等待被填满的未定义空间.任何名字已write结尾的操做都会在当前writerIndex上写入数据,而且将writerIndex的值增长写入的数据数.若是写入操做的参数也是一个ByteBuf, 而且没有元坐标被指定, 那么指定的buffer的readerIndex也会一块儿增长blog
若是没有组合够的空间剩余来写,会抛出IndexOutOfBoundsException. 最新分配的buffer的writerIndex的默认值是0, 包装类和buffer副本的writerIndex是buffer的容量索引
// Fills the writable bytes of a buffer with random integers. ByteBuf buffer = ...; while (buffer.maxWritableBytes() >= 4) { buffer.writeInt(random.nextInt()); }
这个段包含已经被读操做读过的字节.初始化的时候, 这个段的大小为0,这个段的大小会随着读操做一直增长到writerIndex.读字节能够经过discardReadBytes()回收未被使用的区域将其变为丢弃字节, 以下图所示ip
调用discardReadBytes()前:内存
使用discardReadBytes()后:
请注意并不能保证在调用discardReadBytes()后并不能保证可写字节的内容.可写字节在大部分状况下不会移动, 而且可能被彻底不一样的数据填满, 这取决于底层的buffer实现.
你能够经过调用clear()将readerIndex和writerIndex都设为0.这不会清除buffer内容(例如用0填充), 他仅仅是清除了两个指针.请注意这个操做的语义和ByteBuffer.clear()是不同的
clear()前
clear()后
使用indexOf(int, int, byte)和bytesBefore(int, int, byte)能够进行最简单的单字节搜索.bytesBefore(byte)在你处理一个NUL-terminated字符串的时候特别有用.更复杂的搜索, 请使用forEachByte(int, int, ByteBufProcessor)和一个ByteBufProcessor的实现
每一个buffer都有两个标记索引.一个用来保存readerIndex,另外一个用来保存writerIndex.你能够经过调用reset()放来来重置他们中的一个.他的工做方式和InputStream中的mark和reset方法很像, 只是没有readlimit
你能够经过调用duplicate(), slice()或者slice(int, int)来建立一个已存在的buffer的视图.一个派生的buffer会有单独的readerIndex,writerIndex和标记坐标, 可是他共享其余数据.就像一个NIO的buffer同样.
加入你须要一个全新的buffer的copy,请调用copy()方法
假如一个ByteBuf是有一个byte数组做为支持的, 你能够直接经过array()方法访问它. 判断一个buffer是不是被byte array做为支持,调用hasArray()
只有堆内内存的ByteBuf是有array支持的, 若是是堆外内存的ByteBuf, 是不能经过array()获取到数据的, 而CompositeByteBuf可能由堆内的ByteBuf和堆外的DirectByteBuf组成, 他也不能直接经过array()获取数据
若是一个ByteBuf能够被转换为NIO ByteBuffer, 他共享他的内容,你能够经过nioBuffer()获取它.判断一个buffer可否被转化为NIO buffer, 使用nioBufferCount().
各类各样的toString(Charset)方法将一个ByteBuf转化为一个String.请注意toString()并非一个转换方法.
请看ByteBufInputStream和ByteBufOutputStream