1. 基本概念对比

特性 Java IO (OIO/BIO) Java NIO
全称 Blocking IO New IO / Non-blocking IO
核心方向 面向流(Stream) 面向缓冲区(Buffer)
阻塞性 阻塞 非阻塞
通道 单向 双向(Channel)

2. 详细区别

2.1 面向流 vs 面向缓冲区
// IO - 面向流
InputStream in = new FileInputStream("file.txt");
int data = in.read(); // 直接从流读取字节

// NIO - 面向缓冲区
FileChannel channel = FileChannel.open(path);
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer); // 读取到缓冲区
buffer.flip(); // 切换读模式
2.2 阻塞 vs 非阻塞
// IO - 阻塞模式
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept(); // 阻塞直到连接
InputStream in = socket.getInputStream();
in.read(); // 阻塞直到有数据

// NIO - 非阻塞模式
ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false); // 设置为非阻塞
channel.bind(new InetSocketAddress(8080));

SocketChannel client = channel.accept(); // 立即返回,可能为null

Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_ACCEPT);

3. 核心组件

3.1 IO 核心组件
  • InputStream/OutputStream: 字节流

  • Reader/Writer: 字符流

  • File: 文件操作

  • Socket: 网络通信

3.2 NIO 核心组件
// 1. Buffer - 缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("hello".getBytes());
buffer.flip(); // 切换读模式
while(buffer.hasRemaining()) {
    System.out.print((char)buffer.get());
}

// 2. Channel - 通道
FileChannel fileChannel = FileChannel.open(path);
SocketChannel socketChannel = SocketChannel.open();

// 3. Selector - 选择器(多路复用)
Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_READ);

while(true) {
    selector.select(); // 阻塞直到有事件
    Set<SelectionKey> keys = selector.selectedKeys();
    // 处理就绪的事件
}

4. 使用场景对比

场景 推荐 原因
少量连接,大文件 IO 编程简单,适合大文件读写
大量连接,小数据 NIO 高并发,非阻塞IO
实时性要求高 NIO 非阻塞,响应快
开发效率优先 IO API简单,易于理解和维护

5. 代码示例对比

5.1 文件复制
// IO方式
public static void copyFileIO(File source, File dest) throws IOException {
    try (InputStream in = new FileInputStream(source);
         OutputStream out = new FileOutputStream(dest)) {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = in.read(buffer)) > 0) {
            out.write(buffer, 0, length);
        }
    }
}

// NIO方式
public static void copyFileNIO(File source, File dest) throws IOException {
    try (FileChannel inChannel = new FileInputStream(source).getChannel();
         FileChannel outChannel = new FileOutputStream(dest).getChannel()) {
        inChannel.transferTo(0, inChannel.size(), outChannel);
        // 或使用transferFrom
        // outChannel.transferFrom(inChannel, 0, inChannel.size());
    }
}
5.2 网络服务器
// BIO服务器 - 每个连接一个线程
public class BioServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8080);
        while (true) {
            Socket socket = server.accept();
            new Thread(() -> handleRequest(socket)).start();
        }
    }
}

// NIO服务器 - 单线程处理多连接
public class NioServer {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        while (true) {
            selector.select(); // 等待事件
            Set<SelectionKey> keys = selector.selectedKeys();
            keys.forEach(key -> {
                if (key.isAcceptable()) {
                    // 处理连接
                } else if (key.isReadable()) {
                    // 处理读取
                }
            });
            keys.clear();
        }
    }
}

6. 性能比较

指标 IO NIO
线程模型 一个连接一个线程 少量线程处理多连接
内存使用 较高(线程栈) 较低(少量线程)
上下文切换 频繁 较少
数据处理 直接处理 需要buffer管理

7. 选择建议

  1. 选IO的情况

    • 连接数少(<1000)

    • 每个连接数据量大

    • 开发周期短

    • 维护简单优先

  2. 选NIO的情况

    • 连接数多(>1000)

    • 短连接,小数据

    • 高并发场景

    • 需要非阻塞操作

  3. 实际应用

    • 传统应用服务器(Tomcat早期版本)使用BIO

    • 高性能服务器(Netty、Tomcat NIO模式)使用NIO

    • 现代框架(Spring WebFlux)基于NIO

8. 常见问题

  1. NIO的bug:早期版本有epoll空轮询bug

  2. 调试难度:NIO调试更复杂

  3. 代码复杂度:NIO代码更难维护

  4. Buffer管理:需要小心处理buffer的flip、clear等操作

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐