ByteBuf (Netty API Reference (4.1.76.Final))
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.75.Final</version>
</dependency>
package com.example.demo.util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.nio.ByteBuffer;
import java.util.Random;
public class NettyLearn {
public static void main(String[] args) {
//普通的buff 固定大小的堆buff
ByteBuf heapBuffer = Unpooled.buffer(128);
//是固定大小的direct buff direct buff使用的是堆外内存,省去了数据到内核的拷贝,
System.out.println(heapBuffer.readerIndex());
System.out.println(heapBuffer.writerIndex());
while (heapBuffer.isWritable()) {
//一个int类型占四字节
heapBuffer.writeInt(new Random().nextInt());
System.out.println(heapBuffer.writerIndex());
System.out.println(heapBuffer.readerIndex());
}
while (heapBuffer.isReadable()) {
System.out.println(heapBuffer.readInt());
System.out.println(heapBuffer.readerIndex());
}
System.out.println(heapBuffer.readerIndex());
System.out.println(heapBuffer.writerIndex());
heapBuffer = heapBuffer.discardReadBytes();
System.out.println(heapBuffer.readerIndex());
System.out.println(heapBuffer.writerIndex());
while (heapBuffer.isReadable()) {
System.out.println(heapBuffer.readInt());
System.out.println(heapBuffer.readerIndex());
}
while (heapBuffer.isWritable()) {
//一个long类型占8字节
heapBuffer.writeLong(new Random().nextLong());
System.out.println(heapBuffer.writerIndex());
System.out.println(heapBuffer.readerIndex());
}
while (heapBuffer.isReadable()) {
System.out.println(heapBuffer.readLong());
System.out.println(heapBuffer.readerIndex());
}
heapBuffer = heapBuffer.clear();
System.out.println(heapBuffer.readerIndex());
System.out.println(heapBuffer.writerIndex());
System.out.println(heapBuffer.isReadable());
System.out.println(heapBuffer.isWritable());
// 因此效率比普通的buff要高。
ByteBuf directBuffer = Unpooled.directBuffer(256);
//wrappedBuffer是对现有的byte arrays或者byte buffers的封装,可以看做是一个视图,
// 当底层的数据发生变化的时候,Wrapped buffer中的数据也会发生变化。
ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(new byte[128], new byte[256]);
// Copied buffer是对现有的byte arrays、byte buffers 或者 string的深拷贝,
// 所以它和wrappedBuffer是不同的,Copied buffer和原数据之间并不共享数据。
ByteBuf copiedBuffer = Unpooled.copiedBuffer(ByteBuffer.allocate(128));
//随机访问
//ByteBuf也一样,可以通过capacity或得其容量,然后通过getByte方法随机访问其中的byte,如下所示:
// ByteBuf buffer = heapBuffer;
// for (int i = 0; i < buffer.capacity(); i++) {
// byte b = buffer.getByte(i);
// System.out.println((char) b);
// }
//序列读写
// ByteBuf 提供了两个index用来定位读和写的位置,分别是readerIndex 和 writerIndex ,
// 两个index分别控制读和写的位置。
// 下图显示的一个buffer被分成了三部分,分别是可废弃的bytes、可读的bytes和可写的bytes。
// +-------------------+------------------+------------------+
// | discardable bytes | readable bytes | writable bytes |
// | | (CONTENT) | |
// +-------------------+------------------+------------------+
// | | | |
// 0 <= readerIndex <= writerIndex <= capacity
// 上图还表明了readerIndex、writerIndex和capacity的大小关系。
//
//其中readable bytes是真正的内容,可以通过调用read* 或者skip* 的方法来进行访问或者跳过,
// 调用这些方法的时候,readerIndex会同步增加,如果超出了readable bytes的范围,
// 则会抛出IndexOutOfBoundsException。默认情况下readerIndex=0。
//遍历readable bytes
// while (directBuffer.isReadable()) {
// System.out.println(directBuffer.readByte());
// }
// 首先通过判断是否是readable来决定是否调用readByte方法。
//
// Writable bytes是一个未确定的区域,等待被填充。可以通过调用write*方法对其操作,
// 同时writerIndex 会同步更新,同样的,如果空间不够的话,
// 也会抛出IndexOutOfBoundsException。默认情况下 新分配的writerIndex =0 ,
// 而wrapped 或者copied buffer的writerIndex=buf的capacity。
//写入writable bytes
while (wrappedBuffer.maxWritableBytes() >= 4) {
wrappedBuffer.writeInt(new Random().nextInt());
}
//Discardable bytes是已经被读取过的bytes,初始情况下它的值=0,
// 每当readerIndex右移的时候,Discardable bytes的空间就会增加。
// 如果想要完全删除或重置Discardable bytes,则可以调用discardReadBytes()方法,
// 该方法会将Discardable bytes空间删除,将多余的空间放到writable bytes中,如下所示:
// 调用 discardReadBytes() 之前:
// +-------------------+------------------+------------------+
// | discardable bytes | readable bytes | writable bytes |
// +-------------------+------------------+------------------+
// | | | |
// 0 <= readerIndex <= writerIndex <= capacity
//
//
// 调用 discardReadBytes()之后:
// +------------------+--------------------------------------+
// | readable bytes | writable bytes (got more space) |
// +------------------+--------------------------------------+
// | | |
// 调用clear()方法会将readerIndex 和 writerIndex 清零,
// 注意clear方法只会设置readerIndex 和 writerIndex 的值,
// 并不会清空content,看下面的示意图:
// 调用 clear()之前:
// +-------------------+------------------+------------------+
// | discardable bytes | readable bytes | writable bytes |
// +-------------------+------------------+------------------+
// | | | |
// 0 <= readerIndex <= writerIndex <= capacity
//
//
// 调用 clear()之后:
// +---------------------------------------------------------+
// | writable bytes (got more space) |
// +---------------------------------------------------------+
// | |
// 0 = readerIndex = writerIndex <= capacity
}
}