Java IO 流与 Reader
字节流与字符流的职责分层、装饰器组合,以及读写时的编码与缓冲实践。
#type / concept
#status / growing
#tech / dev
#resource / java
[!info] 关联笔记
Java IO 流与 Reader
这个概念为什么出现
文件、网络、进程管道最终都是字节;人类文本还涉及字符编码。Java 经典 IO 分成字节流(InputStream/OutputStream)与字符流(Reader/Writer),并用装饰器叠加缓冲、转换等能力。
[!abstract] 一句话理解 字节流处理原始字节;字符流在 Reader/Writer 层处理文本;用 InputStreamReader 等桥接并显式指定 Charset,缓冲装饰器减少系统调用。
最小可运行示例
场景:读取 UTF-8 配置行并写出备份
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
public class ConfigLineCopy {
static void copyFirstLine(Path src, Path dst) throws IOException {
try (BufferedReader r = Files.newBufferedReader(src, StandardCharsets.UTF_8);
BufferedWriter w = Files.newBufferedWriter(dst, StandardCharsets.UTF_8)) {
String line = r.readLine();
if (line != null) {
w.write(line);
w.newLine();
}
}
}
public static void main(String[] args) throws Exception {
Path src = Files.createTempFile("cfg-", ".txt");
Path dst = Files.createTempFile("cfg-bak-", ".txt");
Files.writeString(src, "mode=prod\n", StandardCharsets.UTF_8);
copyFirstLine(src, dst);
System.out.println(Files.readString(dst, StandardCharsets.UTF_8).trim());
Files.deleteIfExists(src);
Files.deleteIfExists(dst);
}
}
建议运行:
javac ConfigLineCopy.java && java ConfigLineCopy
期望输出:
mode=prod
结合场景再看三个关注点
- 文本用 Reader/Writer + Charset。
- 缓冲是装饰能力,不是另一种数据模型。
- TWR 保证关闭,关闭通常会 flush 写出流。
核心概念与准确模型
1. 字节流
InputStream.read返回 0–255 或 -1 EOS- 适合图片、protobuf、加密 blob
2. 字符流
Reader以 char 为逻辑单位InputStreamReader负责字节→字符解码
3. 装饰器组合
FileInputStream → BufferedInputStream → ...
InputStreamReader → BufferedReader
4. 现代便捷入口
Files.newBufferedReader/WriterFiles.readString/writeString(小文件)
边界情况与反直觉行为
- 默认 charset 方法危险。
- 以 byte 读文本易截断多字节字符。
- 大文件避免一次
readAllBytes。
常见误区
[!warning] 常见误区:二进制当字符流读 压缩包/图片用字节流,否则编码破坏数据。
工程实践
- 统一 UTF-8。
- 缓冲区大小按场景,不玄学调参。
- 网络 IO 设超时(更高层 API)。
- 优先 NIO.2 Path/Files 管理文件路径。
本节总结
- 字节 vs 字符是第一刀
- 装饰器组合能力
- 编码显式 + 资源关闭
自测题
- 何时必须用 InputStream 而不是 Reader?
- BufferedReader 解决什么?
参考答案
- 非文本字节数据或需精确字节协议时。
- 按行高效读取与减少底层读取次数。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| I/O Streams (Oracle Tutorial) | 教程 | 流模型 |
| java.io package | API | 类型入口 |