全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 10 分钟 ✍️ juanwangdev

NIO 核心组件(Channel、Buffer、Selector)

NIO(New IO)采用 Channel-Buffer-Selector 模型,比传统 IO 效率更高。

Channel(通道)

特点

  • 双向传输,可读可写
  • 可异步读写
  • 配合 Buffer 使用

主要实现

Channel 类型说明
FileChannel文件通道
SocketChannelTCP 客户端通道
ServerSocketChannelTCP 服务端通道
DatagramChannelUDP 通道

FileChannel 示例

Java
// 从文件读取
try (FileChannel channel = new FileInputStream("file.txt").getChannel()) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int len = channel.read(buffer);  // 读取到 buffer
}

// 写入文件
try (FileChannel channel = new FileOutputStream("file.txt").getChannel()) {
    ByteBuffer buffer = ByteBuffer.wrap("Hello".getBytes());
    channel.write(buffer);  // 从 buffer 写入
}

// 文件复制(零拷贝)
try (FileChannel src = new FileInputStream("src.txt").getChannel();
     FileChannel dst = new FileOutputStream("dst.txt").getChannel()) {
    dst.transferFrom(src, 0, src.size());  // 直接传输
}

Buffer(缓冲区)

核心 Buffer 类型

Buffer 类型说明
ByteBuffer字节缓冲区(最常用)
CharBuffer字符缓冲区
IntBuffer整数缓冲区
LongBuffer整数缓冲区
FloatBuffer浮点缓冲区
DoubleBuffer双精度缓冲区

Buffer 核心属性

Java
ByteBuffer buffer = ByteBuffer.allocate(1024);

// capacity:缓冲区容量(1024)
int capacity = buffer.capacity();

// position:当前位置
int position = buffer.position();

// limit:操作边界
int limit = buffer.limit();

Buffer 操作流程

Java
ByteBuffer buffer = ByteBuffer.allocate(1024);

// 1. 写入数据
buffer.put("Hello".getBytes());

// 2. 切换为读模式
buffer.flip();  // position=0, limit=写入长度

// 3. 读取数据
byte[] data = new byte[buffer.limit()];
buffer.get(data);

// 4. 清空缓冲区(准备下次写入)
buffer.clear();  // position=0, limit=capacity

flip() 必须调用:写入后切换为读模式,否则无法正确读取。

Heap Buffer vs Direct Buffer

类型创建方式特点
Heap BufferByteBuffer.allocate(n)在 JVM 堆内存,GC 管理
Direct BufferByteBuffer.allocateDirect(n)在本地内存,减少复制,适合大文件
Java
// Heap Buffer
ByteBuffer heapBuffer = ByteBuffer.allocate(1024);

// Direct Buffer
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

Selector(选择器)

作用

  • 监控多个 Channel 的 IO 事件
  • 单线程管理多连接,减少线程开销
  • NIO 多路复用的核心

使用示例

Java
Selector selector = Selector.open();

// 注册 Channel 到 Selector
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);  // 非阻塞模式
serverChannel.register(selector, SelectionKey.OP_ACCEPT);  // 监听连接

// 事件循环
while (true) {
    selector.select();  // 等待事件
    Set<SelectionKey> keys = selector.selectedKeys();
    Iterator<SelectionKey> iter = keys.iterator();

    while (iter.hasNext()) {
        SelectionKey key = iter.next();
        iter.remove();

        if (key.isAcceptable()) {
            // 处理连接
        }
        if (key.isReadable()) {
            // 处理读取
        }
    }
}

SelectionKey 事件类型

事件常量说明
OP_ACCEPT接收连接
OP_CONNECT连接就绪
OP_READ读就绪
OP_WRITE写就绪

要点总结

  • Channel:双向通道,可读可写,异步
  • Buffer:数据容器,flip() 切换读写模式
  • Selector:多路复用器,单线程管理多连接
  • FileChannel.transferFrom() 实现零拷贝
  • Heap Buffer 在 JVM 堆,Direct Buffer 在本地内存
  • Selector 监控 OP_ACCEPT/OP_READ/OP_WRITE 等事件
  • NIO 适合高并发网络 IO,传统 IO 适合简单文件操作

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java IO 流体系
下一篇 → NIO 非阻塞模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库