Netty深入浅出笔记

1. NIO基础
1.1 三大组件
1.1.1 Channel & Buffer
1.1.2 Selector
在使用Selector之前,处理socket连接还有以下两种方法
多线程版设计
线程池版设计
selector 版设计
1.2 ByteBuffer
1.2.1 ByteBuffer 正确使用姿势
使用案例
有一普通文本文件 data.txt,内容为
使用 FileChannel 来读取文件内容
@Slf4j
public class TestByteBuffer {
public static void main(String[] args) {
//FileChannel
//1.输入输出流 2.RandomAccessFile
try (FileChannel channel = new FileInputStream("data.txt").getChannel()){
//准备缓存区
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
while(true){
//从channel中读取数据,想buffer写入
int len = channel.read(byteBuffer);
log.debug("读取到的字节数 {}", len);
if(len == -1){ //读到没有数据了
break;
}
//打印buffer的内容
byteBuffer.flip(); //切换至读模式
while (byteBuffer.hasRemaining()){ //判断是否还有剩余未读的数据
byte b = byteBuffer.get();
log.debug("实际字节 {}", (char) b);
}
byteBuffer.clear(); //切换至写模式
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 读取到的字节数 10
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 1
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 2
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 3
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 4
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 5
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 6
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 7
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 8
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 9
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 0
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 读取到的字节数 4
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 a
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 b
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 c
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 实际字节 d
17:48:36 [DEBUG] [main] c.c.n.c.TestByteBuffer - 读取到的字节数 -1
1.2.2 ByteBuffer结构
一开始
写模式下,position 是写入位置,limit 等于容量,下图表示写入了 4 个字节后的状态
flip 动作发生后,position 切换为读取位置,limit 切换为读取限制
读取 4 个字节后,状态
clear 动作发生后,状态
compact 方法,是把未读完的部分向前压缩,然后切换至写模式
1.2.3 ByteBuffer核心属性
字节缓冲区的父类Buffer中有几个核心属性,如下
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
1.2.4 ByteBuffer常见方法
put()方法
flip()方法
get()方法
rewind()方法
clean()方法
mark()和reset()方法
compact()方法
clear() VS compact()
所以需要根据情况来判断使用哪种方法进行模式切换