一、常见类
| 类 | 类型 | 核心用途 | 典型场景 |
|---|---|---|---|
| FileInputStream / FileOutputStream | 字节流 | 读写二进制文件(图片、视频、压缩包等) | 文件上传下载、复制任意类型文件 |
| FileReader / FileWriter | 字符流 | 读写文本文件(默认编码,易乱码) | 简单配置文件、日志文件读写(注意编码问题) |
| BufferedReader / BufferedWriter | 字符缓冲流 | 带缓冲、按行读写文本,性能高 | 处理大文本、按行解析 CSV/日志 |
| BufferedInputStream / BufferedOutputStream | 字节缓冲流 | 带缓冲的字节读写,减少磁盘 IO | 高效复制大文件、流式处理二进制数据 |
| InputStreamReader / OutputStreamWriter | 转换流 | 字节 → 字符,可指定编码解决乱码 | 读取未知编码文本、网络流转换为字符 |
| PrintWriter | 字符输出流 | 格式化输出文本,支持 print/println/printf,可指定编码 |
生成报告、写 HTML/XML、日志输出到文件 |
| PrintStream | 字节输出流 | 同 PrintWriter,但字节流,System.out 就是它 | 控制台打印、简单调试(日常多用 PrintWriter 写文件) |
注意 :
FileReader/FileWriter使用平台默认编码,易出现乱码。生产环境建议用InputStreamReader/OutputStreamWriter或Files.newBufferedReader指定编码。
二、2 个必须掌握的核心概念
1. 字节流 vs 字符流
- 字节流 (
InputStream/OutputStream):处理任何二进制数据(图片、音视频、压缩包)。 - 字符流 (
Reader/Writer):专门处理文本,内部已经处理了字符编码。 - 选择原则:操作文本优先字符流,否则用字节流。
2. 缓冲流的作用
- 不带缓冲的流每次读写都会触发系统调用(如
read()),效率极低。 - 缓冲流(
BufferedXxx)将数据先读入内存缓冲区,减少 IO 次数,性能可提升数十倍。 - 最佳实践:始终用缓冲流包装底层流(除非数据量极小)。
三、必须掌握的典型代码模式
1. 复制文件(字节缓冲流)
java
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("dst.jpg"))) {
byte[] buffer = new byte[8192];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}
2. 读取文本文件(指定编码,按行)
java
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
3. 写入文本文件(PrintWriter 指定编码)
java
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(new FileOutputStream("out.txt"), StandardCharsets.UTF_8), true)) {
pw.println("Hello 中文");
pw.printf("数值:%d", 123);
}
四、了解即可(日常不常用)
| 类 | 说明 | 了解程度 |
|---|---|---|
DataInputStream/DataOutputStream |
读写 Java 基本类型,用于自定义 RPC 或二进制协议 | 知道存在即可,目前多被 JSON/Protobuf 替代 |
ObjectInputStream/ObjectOutputStream |
Java 原生序列化 | 知道原理、serialVersionUID、transient 即可,实际少用 |
ByteArrayInputStream/ByteArrayOutputStream |
内存中操作字节数组 | 可能会在单元测试或数据转换时用到,简单了解 |