Netty ByteBuf
阅读数:234 评论数: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)