Java IO

一、IO 的第一性原理

1. IO 的本质

无论何种编程语言、何种框架,IO 的本质始终只有一句话:

IO = 数据在不同介质之间的流动

它包含三个核心要素:

数据源(Source) → 数据传输(Stream) → 数据宿(Sink)

从抽象角度看:


2. IO 的核心矛盾

所有 IO 技术的演进,本质上都在解决三对矛盾:

矛盾维度 表现
速度差异 CPU 远快于磁盘/网络
表示差异 字节 vs 字符
同步差异 阻塞 vs 非阻塞

Java IO 的设计,就是围绕这些矛盾构建的一套抽象体系。


二、Java IO 的设计哲学

Java IO 并不是一堆 API,而是一套高度工程化的设计体系,其核心哲学包括:

1. 抽象分层

Java IO 将复杂的 IO 世界拆解为清晰的层次:

应用逻辑层
    ↑
字符处理层(Reader / Writer)
    ↑
字节处理层(InputStream / OutputStream)
    ↑
操作系统 IO

2. 责任分离

Java IO 将功能拆解为:

这正是“节点流 + 处理流”模型的由来。


3. 组合优于继承

Java IO 大量使用:

装饰器模式(Decorator Pattern)

而不是通过继承堆积功能。

例如:

new BufferedInputStream(
    new FileInputStream("a.txt")
)

这种设计带来:


4. 面向抽象编程

应用程序只依赖抽象,而不依赖具体实现。


三、Java IO 的统一认知模型

1. 四层模型

从架构角度看,Java IO 可以抽象为四层:

┌───────────────────────────┐
│       应用层 API           │
└─────────────▲─────────────┘
              │
┌─────────────┴─────────────┐
│        处理流层            │  ← 缓冲、编码、对象化
└─────────────▲─────────────┘
              │
┌─────────────┴─────────────┐
│        节点流层            │  ← 文件、网络、内存
└─────────────▲─────────────┘
              │
┌─────────────┴─────────────┐
│      操作系统 IO          │
└───────────────────────────┘

2. 两大维度

Java IO 的所有类,本质上只解决两个维度问题:

维度 目的
数据形态 字节 or 字符
功能职责 节点 or 处理

四、IO 的类型体系

1. 字节流 vs 字符流

这是 Java IO 中最根本的划分:

类型 抽象 面向
字节流 InputStream / OutputStream 二进制数据
字符流 Reader / Writer 文本数据

本质区别


2. 节点流与处理流

节点流(Node Stream)

代表真实的数据来源或去向:

解决:数据从哪里来、到哪里去

处理流(Filter Stream)

对已有流进行增强:

解决:如何更好地处理数据


3. IO 体系的矩阵结构

可以抽象为一个二维模型:

字节流 字符流
节点流 FileInputStream FileReader
缓冲处理流 BufferedInputStream BufferedReader
转换流 InputStreamReader OutputStreamWriter
对象化流 ObjectInputStream -

五、File 抽象模型

1. File 的本质

Java 中的 File 并不是文件本身,而是:

路径的抽象描述

真正代表操作系统文件的是:

FileDescriptor


2. File 的三层语义

File 类承载三层含义:

层次 含义
路径表示 抽象路径
元数据 文件信息
操作接口 创建/删除

3. File 与流的关系

File → FileInputStream → InputStream

File 只是入口,真正的 IO 行为由流完成。


六、缓冲的工程本质

1. 为什么需要缓冲?

核心原因:

减少系统调用次数

IO 的最大成本在于:

Buffered 流的价值:

多次小 IO → 一次大 IO

2. 缓冲流的定位

BufferedStream 的本质:

用空间换时间


七、编码与解码的本质模型

1. 乱码问题的根源

所有编码问题都可以归结为一句话:

编码与解码使用了不同的字符集


2. Java 中的转换桥梁

字节流 ←→ 字符流

由两个类承担:

它们是:

字节世界与字符世界的桥梁


3. 编码模型

统一认知:

字符(Char) 
   ↕ Charset
字节(Byte)

八、网络 IO 模型

1. IO 的两种驱动模式

模式 思想
Reactor 主动轮询
Proactor 被动回调

2. 线程模型

经典的服务器模型:

1 + N + M

体现的是:

IO 与业务解耦的思想


九、序列化的工程意义

1. 序列化的本质

对象 → 字节流

两大目的:


2. Java 序列化的约束


3. 序列化的工程权衡

方式 特点
Java 原生 稳定但臃肿
Hessian 跨语言
Kryo 高性能
JSON 易读但类型弱

十、IO 技术的演进

1. 从 BIO 到 NIO

Java IO 的发展史:

阶段 特点
BIO 阻塞 + 面向流
NIO 非阻塞 + 面向缓冲区
AIO 真正异步

2. 演进的本质

演进方向始终是:

提高并发能力 + 降低线程成本


十一、IO 的工程选型原则

1. 选择字节流还是字符流?

场景 选择
图片/视频 字节流
文本处理 字符流

2. 是否需要缓冲?

几乎所有生产代码:

都应该使用 Buffered


3. 编码原则

永远遵循:

明确指定编码

关联内容(自动生成)