Buffer
ByteBuffer
常用的缓冲区JDK NIO 类库 java.nio.Buffer
JDK提供的ByteBuffer
可以满足NIO编程,但有其局限性:
ByteBuffer
长度固定,不能自动扩缩容,编程对象POJO大于ByteBuffer
的容量时,或发生索引越界异常ByteBuffer
只有一个标识位置的指针position,读写的时候需要手工调用flip()
和rewind()
等,使用者必须必须小心谨慎地处理这些API,否则很容易导致程序处理失败;ByteBuffer
的API功能有限,一些高级和实用的特性不支持,需要使用者自己编程实现
ByteBuf自动扩容
iAbstractByteBuf#writeByte
调用ensureWritable0
方法
final void ensureWritable0(int minWritableBytes) {
ensureAccessible();
if (minWritableBytes <= writableBytes()) {
return;
}
if (minWritableBytes > maxCapacity - writerIndex) {
throw new IndexOutOfBoundsException(String.format(
"writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s",
writerIndex, minWritableBytes, maxCapacity, this));
}
// Normalize the current capacity to the power of 2.
// 自动扩缩容
int newCapacity = alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity);
// Adjust to the new capacity.
capacity(newCapacity);
}
ByteBuf的工作原理
ButeBuf
依然是个Byte数组的缓冲区,基本功能应该与JDK的ByteBuffer
一致:
- 7种Java基本类型、byte数组、ByteBuffer(ByteBuf)等的读写
- 缓冲区自身的copy和slice等
- 设置网络字节序
- 构造缓冲区实例
- 操作位置指针等方法
Netty ByteBuf是根据ByteBuffer
实现,现有两种策略:
- 参考
JDK ByteBuffer
的实现,增加额外的功能,解决原ByteBuffer
的缺点 - 聚合
JDK ByteBuffer
,通过Facade
模式对其进行包装,可以减少自身代码量,降低实现成本
ByteBuffer的读写
ByteBuffer不做flip操作,读取到将是
position
到capacity
之间的错误内容
ByteBuffer buffer = ByteBuffer.allocate(88);
String value = "Hello World";
buffer.put(value.getBytes())