因为之后想要做一个基于UDP实现可靠传输的项目,但是java网络编程的基础不是很好,所以学一下Netty来补齐一下基础。今天是byteBuffer。
在Java nio中,主要有三大组件:Buffer,Channel和Selector。Buffer提供了一个字节缓冲区,其可以不断的从Channel中读取接收到的数据。
特点:
- 大小不可变。一旦创建,无法改变其容量大小,无法扩容或者缩容;
- 读写灵活。内部通过指针移动来实现灵活读写;
- 支持堆上内存分配和直接内存分配。
属性主要有如图下四个,关于mark需要注意:
- position或limit一旦小于mark则mark会被丢弃;
- 没有定义mark时如果调用了Buffer#reset则会抛出InvalidMarkException。
byteBuffer使用很简单:
-
allocate(int capacity): 分配新的字节缓冲区。
ByteBuffer buffer = ByteBuffer.allocate(10);
-
wrap(byte[] array): 包装一个现有的字节数组,创建一个新的字节缓冲区。
byte[] byteArray = new byte[10];
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
-
put(byte b): 将字节写入缓冲区的当前位置。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65); // 写入ASCII码为65的字节'A'
-
put(byte[] src): 将字节数组写入缓冲区。
ByteBuffer buffer = ByteBuffer.allocate(10);
byte[] byteArray = {65, 66, 67}; // 'A', 'B', 'C'
buffer.put(byteArray);
-
get(): 读取缓冲区的当前位置的字节。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip(); // 切换到读取模式(必须,不然读不出来的)
byte result = buffer.get(); // 读取字节
-
get(byte[] dst): 将缓冲区的字节读取到给定的字节数组中。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip();
byte[] byteArray = new byte[1];
buffer.get(byteArray); // 读取字节到字节数组
-
flip(): 切换缓冲区的读取/写入模式。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip(); // 切换到读取模式
-
clear(): 清空缓冲区,但是数据仍然存在,处于"forgotten but not gone"状态。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip();
buffer.clear(); // 清空缓冲区,准备写入
-
compact(): 将缓冲区中未读取的数据复制到缓冲区的开始位置,然后将位置设置为复制数据的末尾。(注意这个方法,读过的数据会被清除,如果要反复读取,参考rewind方法)
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip();
buffer.get(); // 读取一个字节
buffer.compact(); // 将未读取的数据复制到缓冲区的开始位置
-
remaining(): 返回当前位置与限制之间(limit,见上图)的元素数量。
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 65);
buffer.flip();
int remaining = buffer.remaining(); // 返回1,因为只有一个字节未读取
还有很多方法,没办法一次性列举,