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 体系的矩阵结构

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

字节流字符流
节点流FileInputStreamFileReader
缓冲处理流BufferedInputStreamBufferedReader
转换流InputStreamReaderOutputStreamWriter
对象化流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. 编码原则

永远遵循:

明确指定编码

关联内容(自动生成)