
Channel 通道ByteBuffer 读写缓冲区Selector 多路复用器ByteBuffer的读写操作上。
ByteBuffer为NIO中的字节缓冲区,相对于BIO的Stream流只支持写入或者读取单向操作,ByteBuffer是双向的,支持读和写。
# 属性与方法简介
ByteBuffer.allocateDirect(1024 * 4);ByteBuffer.allocate(1024 * 4);ByteBuffer的容量,这个值在ByteBuffer初始化的时候就确定下来了。不论是在读还是在写模式下,这个值都不变。ByteBuffer的哪个位置,ByteBuffer初始化时,这个值为0。position的最大值为capacity-1。position重置为0,即从ByteBuffer的起始位置开始读取数据。
limit为最大可写入的数据量,即ByteBuffer的最大容量,值为capacity
limit将会被设置为读模式下的position值,即可读取的最大数据量。
position设置为0,即从ByteBuffer起始位置开始读。limit设置为写模式下position的值,即最大可读取的数据量大小。position位置position指向上一次mark()所指向的位置,可以从这个位置重复向下读取数据limit设置为capacityposition指向起始位置0ByteBuffer中的数据并未完全读完,调用这个方法将忽略那些未读取的数据。ByteBuffer中的数据,调用compact()会将position~limit之间的数据拷贝到ByteBuffer的起始处,并且position为剩余数据量的大小,下次再往ByteBuffer中写入数据时,将在position位置继续往下写,不会覆盖历史数据。
byteBuffer.put(x)channel.read(byteBuffer)byteBuffer.get()channel.write(bytebuffer)/**
* ByteBuffer的代码演示
*
* @author futao
* @date 2020/7/7
*/
public class ByteBufferDemo {
public static void main(String[] args) {
// ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024 * 4);
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
// Q: 初始化之后,这三个值分别是多少呢?
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
//向ByteBuffer写入数据
byteBuffer.put("hello, 喜欢天文的pony站长~".getBytes(Constants.CHARSET));
// Q: 向ByteBuffer中写入数据之后,哪些值会发生变化呢?
System.out.println(StringUtils.repeat("=", 10) + "写入数据之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
//将ByteBuffer从写模式调整为读模式
byteBuffer.flip();
//将ByteBuffer从写模式调整为读模式之后,ByteBuffer的哪些值会发生变化?
System.out.println(StringUtils.repeat("=", 10) + "调整ByteBuffer为读模式之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
//从ByteBuffer中读取一个字节
byteBuffer.get();
// Q: 从ByteBuffer中读取一个字节之后,哪些值会发生变化?
System.out.println(StringUtils.repeat("=", 10) + "从ByteBuffer中读取一个字节之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
// 记录一个标记
byteBuffer.mark();
// 继续往下读取
byteBuffer.get();
System.out.println(StringUtils.repeat("=", 10) + "记录一个标记之后继续往下读取" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
//重置position到上一次mark()的标记位置
byteBuffer.reset();
System.out.println(StringUtils.repeat("=", 10) + "reset之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
System.out.println("byteBuffer中是否还有数据:" + byteBuffer.hasRemaining());
//拷贝未读取的数据到缓冲区最前面
byteBuffer.compact();
System.out.println(StringUtils.repeat("=", 10) + "compact之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
//逻辑上清空数据=>实际上只是指针的变化
byteBuffer.clear();
System.out.println(StringUtils.repeat("=", 10) + "clear之后" + StringUtils.repeat("=", 10));
System.out.println("position: " + byteBuffer.position());
System.out.println("capacity: " + byteBuffer.capacity());
System.out.println("limit: " + byteBuffer.limit());
}
}
image.png
是不是与你思考的一致~
https://github.com/FutaoSmile/learn-IO/tree/master/practice/src/main/java/com/futao/practice/chatroom/nio