主要是 ByteBuf , 这个接口封装了java NIO的API, 并且提供了方便的方式,根据不同的子类提供了不策略的实现。
跟java NIO 的 ByteBuffer 不同。 ByteBuf 提供了 readerInex 跟 writerIndex 这两个索引,分别对 read跟write操作时改变其索引。避免的了ByteBuffer中使用 flip() 方式来切换 read/write模式。这种方式适合在读取byte流操作,如在Socket中读取。
通过 write / read 方法获取或写数据,readerIndex 或 writeIndex会递增。
通过set / get 方式获取或写数据不改变readerIndex 跟 writeIndex 则不会改变。
通过clear操作,使得readerInex、writerIndex 。
Heap ByteBuf
使用改实现,ByteBuf中的数据将存储在JVM申请的堆内存中。可以容易的分配跟回收。
Direct ByteBuf
使用改实现,将“直接”的将数据分配到内存中,并不在JVM的堆内存中,分配跟回收是高代价的,Netty 有专门的池化管理。在Soket传输数据中,如果使用的是Heap ByteBuf 的话,JVM将在内部拷贝并转换成Direct Buffer 再将其进行发达。
Composite ByteBuf
改类组合多个 ByteBuf。
对于ByteBuf的一些操作API
/** * * @author XzF */ public class ByteBufOperations { public static void main( String[] args ) { slice(); copy(); getAndset(); readAndWrite(); others(); } private static void slice() { Charset utf8 = Charset.forName( "UTF-8" ); ByteBuf buf = Unpooled.copiedBuffer( "Netty in Action rock!", utf8 ); ByteBuf sliced = buf.slice( 0, 14 ); System.out.println( sliced.toString( utf8 ) ); buf.setByte( 0, (char) 'J' ); // 注意! 下面两值是相等的,说明他们是同一个内容的引用。 System.out.println( (char) buf.getByte( 0 ) ); System.out.println( (char) sliced.getByte( 0 ) ); } private static void copy() { Charset utf8 = Charset.forName( "UTF-8" ); ByteBuf buf = Unpooled.copiedBuffer( "Netty in Action rock!", utf8 ); ByteBuf copy = buf.copy( 0, 14 ); System.out.println( copy.toString( utf8 ) ); buf.setByte( 0, (char) 'J' ); /* * 一个为N , 一个为J ,说明这样操作是安全的,不影响原来buf * 但这个是昂贵的,他代表着要经过内存拷贝 */ System.out.println( (char) buf.getByte( 0 ) ); System.out.println( (char) copy.getByte( 0 ) ); } private static void getAndset() { Charset utf8 = Charset.forName( "UTF-8" ); ByteBuf buf = Unpooled.copiedBuffer( "Netty in Action rock!", utf8 ); System.out.println( (char) buf.getByte( 0 ) ); int readerIndex = buf.readerIndex(); int writerIndex = buf.writerIndex(); System.out.println( "readerIndex : " + readerIndex + ", writerIndex:" + writerIndex ); buf.setByte( 0, (byte) 'B' ); System.out.println( (char) buf.getByte( 0 ) ); /* * 说明 get and set 方法不会移动 readerIndex and writerIndex */ readerIndex = buf.readerIndex(); writerIndex = buf.writerIndex(); System.out.println( "readerIndex : " + readerIndex + ", writerIndex:" + writerIndex ); } private static void readAndWrite() { Charset utf8 = Charset.forName( "UTF-8" ); ByteBuf buf = Unpooled.copiedBuffer( "Netty in Action rock!", utf8 ); System.out.println( (char) buf.readByte() ); int readerIndex = buf.readerIndex(); int writerIndex = buf.writerIndex(); System.out.println( "readerIndex : " + readerIndex + ", writerIndex:" + writerIndex ); buf.writeByte( (byte) '?' ); readerIndex = buf.readerIndex(); writerIndex = buf.writerIndex(); System.out.println( "readerIndex : " + readerIndex + ", writerIndex:" + writerIndex ); } private static void others() { Charset utf8 = Charset.forName( "UTF-8" ); ByteBuf buf = Unpooled.copiedBuffer( "Netty in Action rock!", utf8 ); System.out.println(); System.out.println( "isReadable :" + buf.isReadable() ); System.out.println( "isWritable : " + buf.isWritable() ); System.out.println( "readableBytes :" + buf.readableBytes() ); System.out.println( "writableBytes :" + buf.writableBytes() ); System.out.println( "capacity :" + buf.capacity() ); System.out.println( "maxCapacity :" + buf.maxCapacity() ); System.out.println( "maxHasArray :" + buf.hasArray() ); } }
ByteBufHolder
相当一个有负载占位符。Netty可以进行管理,并池化跟自动释放相关的ByteBuf
data() 返回 ByteBuf
copy() 返回拷贝的ByteBuf
有用的工具类
ByteBufAllocator
分配ByteBuf ,也相当一个工厂方法,可以返回
heapByteBuf 、directByteBuf 、CompositeByteBuf这些类的简单创建方法。
可以通过 Channel的alloc()方法 跟 ChannelHandlerContext的alloc()方法获取。
Unpooled
跟ByteBuffAllocate类功能相当,但在得不到ByteBuffAllocator引用时,使用这个类。获取的是不能共享的ByteBuf。
ByteBufUtil
一个简单的工具类,提供各种编码的实例,以及一些byte转换的帮助方法。