Netty 的数据处理 API 通过两个组件暴露——abstract class ByteBufinterface ByteBufHolder。 ByteBuf的设计源于Java nio的Buffer设计改进,提供了更好更方便的读写分离手段,可以动态增长,可以实现复合缓冲区,并支持引用计数和池化,有着不输nio Buffer的性能和更好的操作方法。

ByteBuf

讨论ByteBuf,可以先从非池化(Unpooled)分支说起。

分配

可以(且推荐)用Unpooled工具类的一系列static方法分配基于内存或direct的ByteBuf,也可以给出underly的字节数组,产生包裹它的ByteBuf。

读写范式

ByteBuf的读写分离的结构设计是它区分于nio Buffer的关键所在。其基本结构如下:

  1. +-------------------+------------------+------------------+
  2. | discardable bytes | readable bytes | writable bytes |
  3. | | (CONTENT) | |
  4. +-------------------+------------------+------------------+
  5. | | | |
  6. 0 <= readerIndex <= writerIndex <= capacity

ByteBuf去除了limit的概念,使用可扩展的capacity;reader/writerIndex都会在当前位置读取/写入后递增,用capacity约束writerIndex,而用writerIndex约束readerIndex,因而只有被写入的字节可被读取。
有了上述读写分离的场景,可以请求readable/writable的字节数,进而规划读写操作。

  • discardReadBytes()可以使所有已经被读取过后的字节失效,同时会对underly的缓存载体做整理,结果如下: ```java BEFORE discardReadBytes()

    1. +-------------------+------------------+------------------+
    2. | discardable bytes | readable bytes | writable bytes |
    3. +-------------------+------------------+------------------+
    4. | | | |
    5. 0 <= readerIndex <= writerIndex <= capacity
  1. AFTER discardReadBytes()
  2. +------------------+--------------------------------------+
  3. | readable bytes | writable bytes (got more space) |
  4. +------------------+--------------------------------------+
  5. | | |

readerIndex (0) <= writerIndex (decreased) <= capacity ```

  • clear()可以清除已读和已写未读的字节,使得buffer回复至初始状态。