nio基础
  # 三大组件
# channel
channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是输入,要么是输出,channel 比 stream 更为底层。
想要向channel中写入数据,必须又buffer写入,如果想从channel中读数据,必须读到buffer。
# 常见的channel
- FileChannel
 - DatagramChannel
 - SocketChannel
 - ServerSocketChannel
 
# buffer
# 常见的buffer
- ByteBuffer
- MappedByteBuffer
 - DirectByteBuffer
 - HeapByteBuffer
 
 - ShortBuffer
 - IntBuffer
 - LongBuffer
 - FloatBuffer
 - DoubleBuffer
 - CharBuffer
 
# selector
selector 的作用就是配合一个线程来管理多个 channel,获取这些 channel 上发生的事件,这些 channel 工作在非阻塞模式下,不会让线程吊死在一个 channel 上。适合连接数特别多,但流量低的场景(low traffic)
调用 selector 的 select() 会阻塞直到 channel 发生了读写就绪事件,这些事件发生,select 方法就会返回这些事件交给 thread 来处理
# 案例
从data.txt中读取数据
@Slf4j
public class ChannelDemo1 {
    public static void main(String[] args) {
        try (RandomAccessFile file = new RandomAccessFile("helloword/data.txt", "rw")) {
            FileChannel channel = file.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(10);
            do {
                // 向 buffer 写入
                int len = channel.read(buffer);
                log.debug("读到字节数:{}", len);
                if (len == -1) {
                    break;
                }
                // 切换 buffer 读模式
                buffer.flip();
                while(buffer.hasRemaining()) {
                    log.debug("{}", (char)buffer.get());
                }
                // 切换 buffer 写模式
                buffer.clear();
            } while (true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
buffer 如何使用?
- 向 buffer 写入数据,例如调用 channel.read(buffer)
 - 调用 flip() 切换至读模式
 - 从 buffer 读取数据,例如调用 buffer.get()
 - 调用 clear() 或 compact() 切换至写模式
 - 重复 1~4 步骤
 
编辑  (opens new window)
  上次更新: 2024/02/22, 14:03:19