Netty ByteBuf

阅读数:15 评论数:0

跳转到新版页面

分类

python/Java

正文

ByteBuf是对字节的封装,有基于堆内存和直接内存。若是堆内存,应用程序无需考虑什么时候释放,因为GC是帮助做,如果是直接内存,那么需要主动释放。

每个ByteBuf对象都有一个引用计数,当这个数值为0时,那么这个对象的方法便无法使用,新创建的ByteBuf对象引用计数值为1,可通过对象的retain和release对这值进行增加和减少

ByteBuf结构

ByteBuf内部有两个指针,提供了顺序的读写操作,读操作有readerIndex(),写操作有writerIndex()。

readerIndex代表从当前位置开始读。

writerIndex代表从当前位置开始写。

capacity代表当前ByteBuf的容量。

0~readerIndex之间的数据是无效的,readerIndex~writerIndex之间的数据是可读的,writerIndex~capacity之间的数据是可写的,当数据不断的增大时,会在maxcapacity范围内对capacity进行扩容。

ByteBuf API

主要有以下几类的常用API

(1)read

移动读指针。

(2)write

移动写指针。

(3)set、get

不会移动指针,在特定的index设置值或获取值。

(4)mark、reset

在读写之前把当前的指针状态保存起来,读写完之后,再调用reset就可以复原原先的操作。这个时候就算进行了读写,也没有改变index。

(5)readableBytes

写指针和读指针之间的数据。

(6)writableBytes

容量和写指针之间的数据

(7)maxWritableBytes

最大容量和写指针之间的数据。

(8)随机访问

        //随机访问
        ByteBuf buffer = heapBuffer;
        for (int i = 0; i < buffer.capacity(); i ++) {
            byte b = buffer.getByte(i);
            System.out.println((char) b);
        }

ByteBuf分类

AbstractByteBuf是对ByteBuf的基本实现,其它的类大都是基于AbstractByteBuf。

   import static io.netty.buffer.Unpooled.*;
  
   ByteBuf heapBuffer    = buffer(128);
   ByteBuf directBuffer  = directBuffer(256);
   ByteBuf wrappedBuffer = wrappedBuffer(new byte[128], new byte[256]);
   ByteBuf copiedBuffer  = copiedBuffer(ByteBuffer.allocate(128));

(1)Pooled和Unpooled

每次从内存中已经分配好的内存中去取还是重新分配内存。

(2)Unsafe和非Unsafe

Unsafe可以直接拿到内存地址,也就是是否使用JDK内部的Unsafe对象直接操作操作系统的内存。

(3)Heap与Direct

Heap直接在堆上分配,参与GC。Direct是在堆外分配,不参与GC,需要手动释放。

ByteBuf与String相互转换

1、String转为ByteBuf

(1)String.getBytes(Charset)将String转为byte[]

(2)使用Unpooled.wrappedBuffer(byte[]),将byte[]转为ByteBuf

String msg = "A message";
byte[] bytes = msg.getBytes(CharsetUtil.UTF_8);
ByteBuf buf = Unpooled.wrappedBuffer(bytes);

或者使用

ByteBuf buf = Unpooled.copiedBuffer("Hello", CharsetUtil.UTF_8);

2、ByteBuf转String

buf.toString(CharsetUtil.UTF_8)