首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Netty精粹之玩转NIO缓冲区(2)

Netty精粹之玩转NIO缓冲区(2)

ByteBuffer指针示意图在JAVA NIO中,原生的ByteByffer家族成员很简单,主要是HeapByteBuffer、DirectByteBuffer和MappedByteBuffer:
  • HeapByteBuffer是基于堆上字节数组为存储结构的缓冲区。
  • DirectByteBuffer是基于直接内存上的内存区域为存储结构的缓冲区。
  • MappedByteBuffer主要是文件操作相关的,它提供了一种基于虚拟内存映射的机制,使得我们可以像操作文件一样来操作文件,而不需要每次将内容更新到文件之中,同时读写效率非常高。

Netty之ByteBuf
相比于ByteBuffer的读写指针position,ByteBuf提供了两个指针readerIndex和writeIndex来分别指向读的位置和写的位置,不需要每次为读写做准备,直接设置读写指针进行读写操作即可。我们看看处于中间状态的状态:

读写中间状态的Buffer
从开始到readerIndex指针之间的这块区域是可以被丢弃的区域,后面会讲到,readerIndex和writerIndex指针之间的区域是可以被读的,writerIndex和capacity指针之间的区域是可以写的区域。当writerIndex指针到达顶端之后,ByteBuf允许用户复用之前已经被读过的区域,调用discardReadBytes方法即可,对应于上面的状态,调用discardReadBytes之后的状态如下:

调用discardReadBytes之后回收可用区域
除了discardReadBytes方法之外,另外一个比较重要的方法就是clear了,clear即清除缓冲区的指针状态,回复到初始值,对应于中间状态的那张图,调用clear之后的状态如下:

调用clear之后,Buffer状态的指针状态得到了初始化

Netty ByteBuf的特点
这里想要比较两种Buffer,对比ByteBuffer得出ByteBuf的优点点,我们首先要做的就是总结ByteBuf的特点以及相比ByteBuffer,这个特点如何成为优点:
(1)ByteBuf读写指针
在ByteBuffer中,读写指针都是position,而在ByteBuf中,读写指针分别为readerIndex和writerIndex,直观看上去ByteBuffer仅用了一个指针就实现了两个指针的功能,节省了变量,但是当对于ByteBuffer的读写状态切换的时候必须要调用flip方法,而当下一次写之前,必须要将Buffe中的内容读完,再调用clear方法。每次读之前调用flip,写之前调用clear,这样无疑给开发带来了繁琐的步骤,而且内容没有读完是不能写的,这样非常不灵活。相比之下我们看看ByteBuf,读的时候仅仅依赖readerIndex指针,写的时候仅仅依赖writerIndex指针,不需每次读写之前调用对应的方法,而且没有必须一次读完的限制。

(2)ByteBuf引用计数
ByteBuf扩展了ReferenceCountered接口,这个接口定义的功能主要是引用计数:
返回列表