javaIO的NIO

一、NIO 整体定位

  • NIO:New IO / Non-blocking IO,JDK1.4 推出
  • 模式:同步非阻塞
  • BIO:面向、单向、阻塞、一连接一线程
  • NIO:面向缓冲区 + 通道、双向、非阻塞、单线程管理多连接
  • 核心价值:高并发、低线程开销,Netty 底层完全基于 NIO 改造

二、NIO 三大核心组件(必背)

  1. Buffer 缓冲区

    数据读写容器,所有数据都先存入 Buffer,再通过 Channel 传输。

  2. Channel 通道

    数据传输通道,双向读写,替代 BIO 单向流。

  3. Selector 选择器

    多路复用核心,1 个线程监听成千上万个 Channel,实现非阻塞。


三、Buffer 缓冲区(核心重点)

1. 常见 Buffer 实现

ByteBuffer(最常用)、CharBuffer、IntBuffer、LongBuffer…

开发 99% 场景只用:ByteBuffer

2. Buffer 四大核心属性

  • capacity:容量,固定不可变,最大存储大小
  • position:当前读写位置
  • limit:读写限制边界
  • mark:标记,可回退

3. 四大核心方法(必考)

  • put():写入数据到缓冲区
  • get():从缓冲区读取数据
  • flip()切换读模式 → position 置 0、limit = 原 position
  • clear()清空缓冲区 → 重置指针,数据并未真正删除

极简代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.nio.ByteBuffer;

public class BufferDemo {
public static void main(String[] args) {
// 分配缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);

// 1. 写模式:存数据
buffer.put("nio学习".getBytes());

// 2. 切换读模式
buffer.flip();

// 3. 读数据
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println(new String(data));

// 4. 清空,恢复写模式
buffer.clear();
}
}

四、Channel 通道

1. 核心特点

  • 双向:既可读、亦可写
  • 非阻塞支持
  • 只能配合 Buffer 传输数据
  • 生命周期长,连接不断开就一直存在

2. 常用 Channel

  • FileChannel:文件 IO 通道
  • SocketChannel:TCP 客户端通道
  • ServerSocketChannel:TCP 服务端通道
  • DatagramChannel:UDP 通道

3. FileChannel 文件复制(NIO 文件操作)

零拷贝思想入门,比 BIO 缓冲流更高效:

1
2
3
4
5
6
7
8
9
try (FileInputStream fis = new FileInputStream("src.txt");
FileOutputStream fos = new FileOutputStream("copy.txt")){

FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();

// 直接通道对传,高效
inChannel.transferTo(0, inChannel.size(), outChannel);
}

4. 分散读取 & 聚集写入

  • 分散读取:一个通道数据,拆分存入多个 Buffer

  • 聚集写入:多个 Buffer 数据,合并写入一个通道

    适合报文定长分段场景,底层网络框架常用。


五、Selector 选择器(多路复用核心)

1. 解决的问题

BIO:客户端多 → 线程爆炸、内存耗尽、上下文切换频繁

NIO+Selector:单线程轮询监听所有通道 IO 事件,无事件就不阻塞。

2. 监听 4 种事件

1
2
3
4
- OP_ACCEPT:客户端连接事件
- OP_CONNECT:客户端连接成功
- OP_READ:读就绪事件
- OP_WRITE:写就绪事件

3. 工作流程

  1. 创建 Selector
  2. 打开 ServerSocketChannel,设置非阻塞
  3. 通道注册到 Selector,并绑定监听事件
  4. 调用 select() 阻塞等待就绪事件
  5. 遍历就绪集合,处理连接 / 读 / 写

六、网络 NIO 核心逻辑(面试高频)

核心对比

  • BIO:一个 Socket 连接 = 一个新线程
  • NIO:一个 Selector 线程 管理 所有连接 Channel

关键配置

所有网络通道必须手动设置:

1
2
// 设置非阻塞模式
serverSocketChannel.configureBlocking(false);

简易 NIO 服务端结构(伪代码逻辑)

  1. 开启 ServerSocketChannel
  2. 绑定端口、非阻塞
  3. 注册到 Selector,监听 ACCEPT
  4. select () 阻塞等待
  5. 有客户端接入 → 拿到 SocketChannel
  6. SocketChannel 设为非阻塞,注册 READ 事件
  7. 客户端发数据 → 触发 READ,读取 Buffer 处理

七、NIO 关键特性总结

  1. 面向**缓冲区 (Buffer)+ 通道 (Channel)**,而非单向流
  2. 同步非阻塞:线程不会卡死等待 IO
  3. 多路复用:Selector 单线程管理多连接
  4. 双向通信:Channel 可读可写
  5. 适合高并发连接场景,不适合大文件单次传输

javaIO的NIO
http://hanqichuan.com/2026/04/20/java的IO/javaIO的NIO/
作者
韩启川
发布于
2026年4月20日
许可协议