InputStreamReader 是将字节流按指定字符集解码为字符流的桥梁类,必须显式指定编码(如 "UTF-8"),否则易乱码;它无缓冲,应配合 BufferedReader 使用以提升效率。

InputStreamReader 是 Java 中用于将字节流(InputStream)按指定字符编码“解码”为字符流(Reader)的桥梁类。它本身不直接“转换字节为字符”,而是让程序能以字符方式读取原始字节数据,关键在于**指定正确的字符集(Charset)**,否则容易乱码。
核心用法:绑定输入流 + 指定编码
创建 InputStreamReader 时,必须传入一个 InputStream(如 FileInputStream、System.in),并推荐显式指定字符集(如 "UTF-8")。不指定时会使用平台默认编码,极不可靠。
- ✅ 推荐写法(明确编码):
new InputStreamReader(inputStream, "UTF-8") - ⚠️ 避免写法(依赖系统默认):
new InputStreamReader(inputStream)(Windows 常是 GBK,Linux/macOS 常是 UTF-8)
典型场景:读取文本文件
例如读取一个 UTF-8 编码的 data.txt 文件:
try (FileInputStream fis = new FileInputStream("data.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line); // 正确按 UTF-8 解码后的字符串
}
}
说明:这里 InputStreamReader 负责把 fis 的字节按 UTF-8 规则转成 Java 的 char,BufferedReader 在其基础上提供按行读取能力。
立即学习“Java免费学习笔记(深入)”;
注意缓冲与效率
InputStreamReader 本身**不带内部缓冲区**,每次 read() 都可能触发底层 I/O。实际使用中,应总是包装在 BufferedReader 中提升性能:
- ❌ 不推荐(低效):
isr.read() —— 每次都读一个字符,频繁系统调用 - ✅ 推荐(高效):
br.readLine() 或 br.read(char[]) —— 批量读取、自动缓存
常见问题:为什么还是乱码?
乱码几乎只由一个原因导致:实际文件编码 ≠ InputStreamReader 指定的编码。排查步骤:
- 确认文件真实编码(可用编辑器如 VS Code、Notepad++ 查看底部状态栏)
- 确保
InputStreamReader构造时传入的字符串与之完全一致(如"GBK"、"ISO-8859-1") - 避免用
"UTF-8"强解 GBK 文件,或反之;若不确定,可尝试StandardCharsets.UTF_8等标准常量代替字符串字面量


















