背景与动机
IO 用于让程序和外部世界交换数据,例如读写文件、处理网络数据、读取配置等。
Java IO 学习时先抓住两条主线:
- 字节流:处理原始字节,适合图片、压缩包、二进制文件。
- 字符流:处理文本字符,适合文本文件。
核心原理拆解
1. 字节流和字符流

字节流常见抽象:
InputStreamOutputStream
字符流常见抽象:
ReaderWriter
如果处理文本,优先关注字符编码;如果处理二进制数据,优先使用字节流。
2. IO 流还可以怎么分类
除了字节流 / 字符流,面试和文档里还常从下面三个角度划分:
| 划分方式 | 分类 | 说明 |
|---|---|---|
| 按流向 | 输入流、输出流 | 数据读入还是写出 |
| 按操作单元 | 字节流、字符流 | 按字节还是按字符处理 |
| 按角色 | 节点流、处理流 | 直接连数据源,还是包一层增强功能 |
常见基类:
- 字节流:
InputStream、OutputStream - 字符流:
Reader、Writer
处理流例如 BufferedReader、BufferedInputStream,用来缓冲、提速,本身不直接连文件。

BIO、NIO、AIO 以及 Netty 属于网络 IO 模型专题,内容较多,见 Java BIO、NIO、AIO 与 Netty。
3. Files 工具类适合简单文件操作
读取文本:
String text = Files.readString(Path.of("demo.txt"));写入文本:
Files.writeString(Path.of("demo.txt"), "hello");对于小文件和学习场景,Files 非常直接。
常用方法速查:
| 方法 | 作用 |
|---|---|
Files.exists() | 判断路径是否存在 |
Files.createFile() | 创建新文件 |
Files.createDirectory() | 创建目录 |
Files.delete() | 删除文件或目录 |
Files.deleteIfExists() | 存在则删除 |
Files.copy() | 复制文件 |
Files.move() | 移动/重命名 |
Files.size() | 查看文件大小 |
Files.readString() | 一次性读文本 |
Files.writeString() | 一次性写文本 |
Files.newBufferedReader() | 按行读取 |
Files.newBufferedWriter() | 缓冲写入 |
示例:
Path path = Path.of("demo.txt");
if (!Files.exists(path)) { Files.createFile(path);}
Files.writeString(path, "hello");System.out.println(Files.size(path));Files.copy(path, Path.of("demo-copy.txt"));Files.deleteIfExists(path);4. try-with-resources 自动关闭资源
try (BufferedReader reader = Files.newBufferedReader(Path.of("demo.txt"))) { String line = reader.readLine(); System.out.println(line);}放在 try (...) 中的资源会在代码块结束后自动关闭,减少资源泄漏风险。
5. IO 操作通常会抛出异常
文件不存在、没有权限、磁盘异常等都可能导致 IO 失败。所以很多 IO API 会抛出 IOException,调用方需要处理或继续声明。
最小可运行代码示例
import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;
public class IoDemo { public static void main(String[] args) throws IOException { Path path = Path.of("demo.txt");
Files.writeString(path, "hello java"); String text = Files.readString(path);
System.out.println(text); Files.deleteIfExists(path); }}常见陷阱与错误示例
1. 忘记关闭流
手动打开流后不关闭,可能导致文件句柄泄漏。优先使用 try-with-resources。
2. 忽略字符编码
文本读写如果编码不一致,可能出现乱码。真实项目中应明确输入输出编码策略。
3. 把大文件一次性读进内存
Files.readString 适合小文件。大文件应考虑逐行读取或分块处理。
面试高频问题
1. Java 中 IO 流分几种
可按流向分输入/输出,按单元分字节/字符,按角色分节点流/处理流。基类是 InputStream/OutputStream 和 Reader/Writer。
2. 字节流和字符流有什么区别
字节流处理原始字节,适合二进制数据;字符流处理字符,适合文本数据,并涉及字符编码。
3. try-with-resources 解决什么问题
它能自动关闭实现了 AutoCloseable 的资源,减少忘记关闭流导致的资源泄漏。
4. BIO、NIO、AIO 有什么区别
见 Java BIO、NIO、AIO 与 Netty 专题笔记。
5. Files 常用方法有哪些
常见有 exists、createFile、createDirectory、delete、copy、move、size、readString、writeString、newBufferedReader 等,适合简单文件读写。
6. 为什么 IO 方法常常要处理 IOException
因为文件和外部资源不完全受程序控制,可能出现不存在、无权限、读写失败等情况。
一句话总结
Java IO 的基础判断是:文本优先字符和编码,二进制优先字节;资源打开后要可靠关闭,简单文件读写可以先用 Files。网络 IO 模型与 Netty 见专题笔记。