三、Netty之ByteBuf

72 阅读2分钟

Netty之ByteBuf

网络数据的基本单位总是字节,Java NIO 提供了ByteBuffer作为它的字节容器,但是其过于复杂且繁琐。

Netty的ByteBuffer替代品是ByteBuf,一个强大的实现,即解决了JDK API的局限性,又为网络应用程序的开发者提供了更好的API。

ByteBuf维护了两个不同的索引:一个用于读取、一个用于写入。当你从ByteBuf读取时,它的readerIndex将会被递增已经被读取的字节数。同样地,当你写入BytBuf时,它的writerIndex也会被递增。当readerIndex和writeIndex到达同样的值时,则将会到达可以读取的数据的末尾。试图读取超出该点的数据将会触发一个indexOutOfBoundsException。

ByteBuf的创建和方法

public void myBytebuf() {
	// 堆外创建缓存区
	// 第一个参数是初始化时的容量,第二个参数是扩容的最大容量
	ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(8, 20);
	// 使用非池化方式,堆内创建缓存区。非池化的缓存无法重复使用,使用完后需要手动释放
//        ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.heapBuffer(8, 20);
	// 使用池化方式,堆内创建缓存区。池化的缓存可以重复使用,会自动释放,无需手动释放
//        ByteBuf buf = PooledByteBufAllocator.DEFAULT.heapBuffer(8, 20);

	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);

	buf.writeBytes(new byte[]{1, 2, 3, 4});
	print(buf);
}

public static void print(ByteBuf buf) {
	// isReadable方法是判断缓存是否可读,没有数据时返回false,有数据返回true
	System.out.println("buf.isReadable()    :" + buf.isReadable());
	// readerIndex方法返回当前读索引的值
	System.out.println("buf.readerIndex()   :" + buf.readerIndex());
	// readableBytes方法返回缓存中还有多少字节的数据未读取
	System.out.println("buf.readableBytes() " + buf.readableBytes());
	// isWritable方法是判断缓存是否可写,缓存没有空间返回false,缓存还有空间返回true
	System.out.println("buf.isWritable()    :" + buf.isWritable());
	// writerIndex方法返回当前写索引的值
	System.out.println("buf.writerIndex()   :" + buf.writerIndex());
	// writableBytes方法返回缓存中还有多少空闲空间
	System.out.println("buf.writableBytes() :" + buf.writableBytes());
	// capacity方法返回当前缓存申请的空间
	// 由于ByteBuf是会扩容的,所以申请的空间会动态变化
	// 当缓存没有空闲空间,并且还在往里写数据时,如果缓存空间没有达到最大值,ByteBuf会申请空间
	System.out.println("buf.capacity()  :" + buf.capacity());
	// maxCapacity方法返回缓存可以申请的最大空间
	System.out.println("buf.maxCapacity()   :" + buf.maxCapacity());
	// isDirect方法判断缓存是否是堆外,是返回true,不是返回false
	System.out.println("buf.isDirect()  :" + buf.isDirect());
	System.out.println("--------------------");
}