美文网首页
Netty ByteBuf

Netty ByteBuf

作者: 歌哥居士 | 来源:发表于2019-03-28 08:46 被阅读0次

与NIO的ByteBuffer相比

  • 可以自定义缓冲区。
  • 零拷贝。
  • 容量按需增长。
  • 读与写模式不需要flip()方法。
  • 读和写使用了不同的索引(readIndex和writeIndex)。
  • 支持方法的链式调用。
  • 支持引用计数。
  • 支持池化。

使用模式
1.堆缓冲区

ByteBuf heapBuf = Unpooled.copiedBuffer("Hi", Charset.forName("UTF-8"));
if (heapBuf.hasArray()) { // 是否是一个支撑数组(backing array)
    int length = heapBuf.readableBytes(); // 获取可读字节数
    byte[] array = heapBuf.array(); // 获取数组
    int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); // 计算第一个字节的偏移量
    System.out.println(new String(array,offset,length));
}

2.直接缓冲区

ByteBuf directBuf = Unpooled.directBuffer().writeBytes("Hi".getBytes());
if (!directBuf.hasArray()) { // 不是一个支持数组则是直接缓冲区
    int length = directBuf.readableBytes(); // 获取可读字节数
    byte[] array = new byte[length]; // 分配数组
    directBuf.getBytes(directBuf.readerIndex(), array); // 将内容读到array中
    System.out.println(new String(array, 0, length));
}

3.混合缓冲区

CompositeByteBuf msgBuf = Unpooled.compositeBuffer(); // 复合缓冲区
ByteBuf headerBuf = Unpooled.copiedBuffer("hi", Charset.forName("UTF-8"));
ByteBuf bodyBuf = Unpooled.directBuffer().writeBytes("baozi".getBytes());
msgBuf.addComponents(headerBuf, bodyBuf); // 复合缓冲区既可以包含堆也可以有直接缓冲区

msgBuf.removeComponent(0); // 删除掉headerBuf
msgBuf.forEach(buf -> System.out.println(buf));

字节操作
readByte(s)和writeByte(s)都会增加readIndex和writeIndex,setByte和getByte不会。

ByteBuf buf = Unpooled.copiedBuffer("Baozi", Charset.forName("UTF-8"));
// 读取所有数据
while (buf.isReadable()) {
    System.out.print((char) buf.readByte());
}

// 写数据
while (buf.writableBytes() > 4) {
    buf.writeBytes("HI".getBytes());
}

索引管理

buf.markReaderIndex();
buf.markWriterIndex();
buf.resetReaderIndex();
buf.resetWriterIndex();

派生缓冲区,修改了派生的缓冲区也会修改原本的
slice、duplicate、order、readSlice、Unpooled.unmodifiableBuffer(..)

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
ByteBuf sliced = buf.slice(0, 15);
System.out.println(sliced.toString(utf8));
buf.setByte(0, (byte) 'J');
//J   J
System.out.println((char) buf.getByte(0) + "   " + (char) sliced.getByte(0));

copy:与slice不同的就是不共享数据

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
// 派生缓冲区,修改了派生的缓冲区也会修改原本的
ByteBuf copy = buf.copy(0, 15);
System.out.println(copy.toString(utf8));
buf.setByte(0, (byte) 'J');
//J  N
System.out.println((char) buf.getByte(0) + "  " + (char) copy.getByte(0));

Unpooled缓冲区

  • buffer,返回未池化的堆内存的ByteBuf
  • directBuffer,返回未池化的直接内存的ByteBuf
  • wrappedBuffer,返回一个包装了给定数据的ByteBuf
  • copiedBuffer,反悔了一个复制了给定数据的ByteBuf

ByteBufUtil

  • hexdump,十六进制打印ByteBuf内容
  • equals,判断两个ByteBuf是否相等

相关文章

网友评论

      本文标题:Netty ByteBuf

      本文链接:https://www.haomeiwen.com/subject/hcdqvqtx.html