Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

    • Java IO概述
    • IO基础

    • 常用IO流

    • 文件与目录操作

    • Java NIO

      • NIO概述
      • Buffer缓冲区
      • Channel通道
      • Selector多路复用
      • SocketChannel网络编程
      • NIO与IO对比
        • 1. 核心差异
        • 2. 文件读写场景
        • 3. 网络通信场景
        • 4. 阻塞和非阻塞
        • 5. 同步和异步
        • 6. 如何选择
        • 专家实践清单
        • Tips 快问快答
        • 7. 总结
    • 高级主题

    • 实践与性能优化

    • 面试与设计题

    • IO实践速查

  • JVM

目录

NIO与IO对比

传统 IO 和 NIO 没有绝对优劣,只有适用场景不同。很多线上问题不是因为用了传统 IO,而是因为在不合适的场景中选择了不合适的模型。

# 1. 核心差异

对比项 传统 IO NIO
编程模型 面向流 面向 Buffer 和 Channel
网络模式 通常阻塞 支持非阻塞
多连接处理 常见一连接一线程 一个线程可管理多个连接
学习成本 低 高
代码复杂度 低 高
典型场景 文件读写、简单网络 高并发网络、文件高级操作

# 2. 文件读写场景

普通文件读写中,传统 IO 已经足够好:

try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
    String line;
    while ((line = reader.readLine()) != null) {
        // process line
    }
}

当需要随机访问、大文件复制、内存映射、零拷贝时,NIO 更有优势:

source.transferTo(0, source.size(), target);

# 3. 网络通信场景

传统 BIO:

一个连接 -> 一个线程 -> 阻塞 read

优点是代码简单,适合连接少、请求少、教学和内部小工具。

NIO:

多个连接 -> 一个 Selector -> 少量线程处理就绪事件

适合大量连接、长连接、高并发网关、消息推送等场景。

# 4. 阻塞和非阻塞

阻塞 IO 中,线程发起 IO 操作后,如果数据未就绪,线程会等待。

非阻塞 IO 中,操作会立即返回:

  • 有数据就处理。
  • 没数据返回 0 或特定状态。
  • 程序可以继续处理其他连接。

非阻塞不是更快地完成一次 IO,而是让线程在等待 IO 时不被浪费。

# 5. 同步和异步

传统 IO 和 NIO Selector 通常都属于同步 IO:应用线程仍然需要主动读取或写入。

AIO 更接近异步 IO:发起操作后,由系统完成后回调或通知。

常见理解:

  • BIO:同步阻塞。
  • NIO:同步非阻塞。
  • AIO:异步非阻塞。

这是宏观分类,具体实现会受操作系统影响。

# 6. 如何选择

优先使用传统 IO 或 Files 的情况:

  • 读取配置文件。
  • 写日志类文本。
  • 小文件处理。
  • 简单导入导出。
  • 开发工具脚本。

考虑 NIO 的情况:

  • 大量长连接。
  • 高性能 TCP 服务。
  • 文件零拷贝。
  • 大文件随机访问。
  • 内存映射。
  • 需要 Selector 多路复用。

考虑成熟框架的情况:

  • 需要自定义高性能网络协议。
  • 需要连接管理、编解码、心跳、超时、背压。
  • 需要跨平台稳定性和可维护性。

这时通常选择 Netty,而不是直接手写 NIO。

# 专家实践清单

判断维度 传统 IO NIO
编程复杂度 低 高
普通文件处理 足够好 可用于高级优化
高并发连接 线程成本高 更适合
协议处理 简单阻塞模型 需要状态机
团队维护 容易 要求更高

选型流程:

普通文件/低连接数
  └─ 优先传统 IO 或 Files

大量长连接/高并发网络
  └─ 使用 NIO 模型,优先成熟框架

纯文件搬运性能瓶颈
  └─ 评估 FileChannel / 零拷贝

# Tips 快问快答

Q:NIO 一定比传统 IO 快吗? A:不一定,取决于场景、实现和瓶颈。

Q:传统 IO 最大优势是什么? A:模型简单,可读性和维护成本低。

Q:NIO 最大优势是什么? A:能用较少线程管理大量连接和事件。

Q:普通文件读写需要 NIO 吗? A:多数不需要,Files 和缓冲流通常足够。

Q:高并发 TCP 服务为什么偏向 NIO? A:连接数多时一连接一线程成本太高,多路复用更合适。

Q:NIO 最大复杂度来自哪里? A:事件驱动、协议状态、半包半写、连接生命周期。

Q:为什么常推荐 Netty 而不是手写 NIO? A:Netty 封装了事件模型、缓冲、编解码、线程模型和大量边界问题。

Q:资深工程师如何选择 IO 模型? A:看连接规模、延迟目标、团队能力、故障排查和维护成本。

# 7. 总结

传统 IO 简单可靠,适合大部分普通业务文件处理。NIO 提供更强的性能和并发能力,但复杂度更高。资深工程师的选择标准不是“哪个更高级”,而是场景、复杂度、团队维护能力和可观测性。

上次更新: 2026/06/25, 14:19:18
SocketChannel网络编程
RandomAccessFile

← SocketChannel网络编程 RandomAccessFile→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式