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

NIO

NIO(Non-blocking IO)是Java 1.4引入的新IO API,支持面向缓冲区、基于通道的IO操作。

NIO概述

NIO含义

  • Non-blocking IO(非阻塞IO)
  • 也称为New IO

NIO与传统IO的区别

对比项传统IONIO
面向对象流(Stream)缓冲区(Buffer)+通道(Channel)
数据流向单向双向(可读可写)
阻塞模式阻塞支持非阻塞
效率一般更高(利用系统原生IO)
适用场景简单文件读写高并发网络IO、大文件

NIO核心组件

三大核心

  1. Buffer:缓冲区,存储数据
  2. Channel:通道,传输数据
  3. Selector:选择器,多路复用(网络IO)

工作模式

Java
数据源 ←────── Channel ←────── Buffer ←────── 程序
(文件)                    (缓冲区)

Buffer缓冲区

Buffer的作用

在内存中存储数据,程序读写Buffer,Buffer与Channel交互。

常用Buffer类型

Buffer类型说明
ByteBuffer字节缓冲区(最常用)
CharBuffer字符缓冲区
IntBuffer整数缓冲区
LongBuffer长整数缓冲区

Buffer核心属性

属性说明
capacity容量,Buffer最大数据量
position当前读写位置
limit限制,可用数据的边界

Buffer使用流程

Java
// 1. 创建Buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);  // 分配1024字节

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

// 3. 切换为读模式
buffer.flip();  // position置0,limit置已写数据量

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

// 5. 清空,准备再次写入
buffer.clear();  // position置0,limit置capacity

关键:写后必须flip()切换为读模式,读后clear()清空准备下次写入。

Channel通道

Channel的作用

连接数据源,负责数据传输,可双向读写。

常用Channel类型

Channel类型说明
FileChannel文件通道
SocketChannelTCP网络通道
DatagramChannelUDP网络通道

FileChannel使用

从文件读取

Java
// 创建FileChannel
FileChannel channel = new FileInputStream("test.txt").getChannel();

// 创建Buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);

// 从Channel读取到Buffer
int bytesRead = channel.read(buffer);
while (bytesRead != -1) {
    buffer.flip();  // 切换为读模式
    // 处理buffer数据
    buffer.clear(); // 清空准备下次读取
    bytesRead = channel.read(buffer);
}
channel.close();

写入文件

Java
FileChannel channel = new FileOutputStream("test.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Hello World".getBytes());
buffer.flip();  // 切换为读模式
channel.write(buffer);  // 从Buffer写到Channel
channel.close();

文件复制(高效)

Java
FileChannel src = new FileInputStream("source.jpg").getChannel();
FileChannel dest = new FileOutputStream("target.jpg").getChannel();

// transferTo高效复制(底层优化)
src.transferTo(0, src.size(), dest);

src.close();
dest.close();

Selector选择器

Selector的作用

多路复用,一个线程管理多个Channel,适合高并发网络应用。

使用场景

  • 服务器需要同时处理多个客户端连接
  • 避免为每个连接创建线程
  • 非阻塞模式提高并发能力

基本流程(网络IO)

text
// 1. 创建Selector
Selector selector = Selector.open();

// 2. 注册Channel到Selector
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);  // 设置非阻塞
channel.register(selector, SelectionKey.OP_READ);  // 注册读事件

// 3. 选择就绪的Channel
while (true) {
    int readyCount = selector.select();  // 等待事件
    if (readyCount == 0) continue;
    
    Set<SelectionKey> keys = selector.selectedKeys();
    for (SelectionKey key : keys) {
        if (key.isReadable()) {
            // 处理读取
        }
    }
    keys.clear();
}

Selector用于网络IO,文件IO通常不需要Selector。

NIO适用场景

场景推荐
简单文件读写传统IO + 缓冲流
大文件复制NIO FileChannel.transferTo
高并发网络服务器NIO + Selector
少量连接客户端传统IO即可

建议:简单场景用传统IO,高并发/大文件用NIO。

要点总结

  • NIO面向缓冲区,传统IO面向流
  • NIO核心:Buffer、Channel、Selector
  • Buffer存储数据,flip/clear切换读写模式
  • Channel双向传输,FileChannel处理文件
  • Selector多路复用,适合高并发网络
  • 简单场景传统IO,高并发/大文件用NIO
  • transferTo高效复制大文件

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

← 上一篇 File类
下一篇 → 字节流与字符流
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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