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()
所以需要根据情况来判断使用哪种方法进行模式切换










