ByteBuf有两个索引,readerIndex和writerIndex,起始位置都是0。当readerIndex大于writerIndex时则会触发IndexOutOfBoundsException
以read或write开头的方法,会移动索引,而以set或get开头的方法则不会。
可以指定ByteBuf的最大容量,但是不能超过Integer.MAX_VALUE ####派生缓冲区 生成方式:
- duplicate();
- slice();
- slice(int,int);
- Unpooled.unmodifiableBuffer(...);
- order(ByteOrder);
- readSlice(int); slice和copy的区别:slice方法获取的切片与源ByteBuf共享数据,copy方法获取的ByteBuf为副本,不与源ByteBuf共享数据。
####ByteBuf 使用模式
- 堆缓冲区
ByteBuf heapBuf = ...;if (heapBuf.hasArray()) { // 检查ByteBuf 是否有一个支撑数组 byte[] array = heapBuf.array(); // 如果有,则获取对该数组的引用 int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); // 计算第一个字节的偏移量。则获取对该数组的引用 int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); // 计算第一个字节的偏移量。}复制代码
- 直接缓冲区
ByteBuf directBuf = ...; if (!directBuf.hasArray()) { ← -- 检查ByteBuf 是否由数组支撑。如果不是,则这是一个直接缓冲区int length = directBuf.readableBytes(); ← -- 获取可读字节数 byte[] array = new byte[length]; ← -- 分配一个新的数组来保存具有该长度的字节数据directBuf.getBytes(directBuf.readerIndex(), array); ← -- 将字节复制到该数组 handleArray(array, 0, length); ← -- 使用数组、偏移}复制代码
- 复合缓冲区
####ByteBuf分配
按需分配:ByteBufAllocator接口
Channel channel = ...;ByteBufAllocator allocator = channel.alloc(); ← -- 从Channel 获取一个到ByteBufAllocator 的引用ChannelHandlerContext ctx = ...;ByteBufAllocator allocator2 = ctx.alloc(); ← -- 从ChannelHandlerContext 获取一个到By复制代码
Unpooled缓冲区