- ByteBuf 和 ByteBuffer的区别
- ByteBuffer
- 相关api
- ByteBuf
- 如何使用
- 参考资料
对于ByteBuffer,其主要有五个属性:mark,position,limit,capacity和array。
这五个属性的作用如下:
- mark:记录了当前所标记的索引下标;
- position:表示当前位置;
- limit:对于写入模式,表示当前可以写入的数组大小,默认为数组的最大长度,对于读取模式,表示当前最多可以读取的数据的位置下标;
- capacity:表示当前数组的容量;
- array:保存了当前写入的数据。
- mark(): 用mark记录当前position的位置;
public final Buffer mark() {
mark = position;
return this;
}
- reset() : 将position恢复到mark的位置;如果没有mark,抛出InvalidMarkException异常;
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
- flip(): 切换为读取模式,limit置为当前position位置,然后将position和mark重置。
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
- rewind(): 重置状态。
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
- compact(): 将数据左移position个位置,直至position=0,然后将position置为limit-position;有不同的实现。
ByteBuffer缺点
- 长度固定,一旦分配完成,它的容量不能动态扩展和收缩,当需要编码的POJO对象大于ByteBuffer的容量时,会发生索引越界异常;
- 只有一个位置指针position,读写时需手工调用flip()和rewind()等;
- API功能有限;
ByteBuf优点
- 容量可以按需增长
- 读写模式切换不需要调用flip()
- 读写使用了不同的索引
- 支持方法的链式调用
- 支持引用计数
- 支持池化
- 可以被用户自定义的缓冲区类型扩展
- 通过内置的复合缓冲区类型实现透明的零拷贝
当调用 discardReadBytes() ,会将已读字节丢弃,并设置readerIndex=0,writerIndex=M。
推荐通过一个Unpooled的工具类来创建新的buffer而不是通过构造器来创建
参考资料- ByteBuf 和ByteBuffer的区别



