Java中字节流读中文易乱码,因其按字节读取且不处理编码;须用InputStreamReader(指定UTF-8等编码)转为字符流,再配BufferedReader高效逐行读取。

Java 中字节流(如 FileInputStream)直接读取中文文本文件时容易乱码,根本原因是它按字节读取,不处理字符编码;而中文在 UTF-8、GBK 等编码下占多个字节,字节流无法自动识别边界和编码规则。要正确读取中文,必须改用字符流(如 InputStreamReader + BufferedReader),显式指定字符编码。
用 InputStreamReader 包装字节流,指定编码
InputStreamReader 是字节流到字符流的桥梁,它把原始字节按指定编码(如 UTF-8、GBK)解码成 Java 的 Unicode 字符:
- 构造时传入
FileInputStream和编码名字符串(如"UTF-8") - 编码名必须与文件实际保存的编码一致,否则仍会乱码
- 推荐优先使用
"UTF-8",兼容性好;若文件是 Windows 记事本默认保存的,可能是"GBK"或"GB2312"
配合 BufferedReader 提高效率和易用性
InputStreamReader 本身支持逐字符读取,但逐字符效率低、操作不便。加上 BufferedReader 可以:
- 缓冲读取,减少 I/O 次数,提升性能
- 提供
readLine()方法,一行一行读取,天然适合文本处理 - 避免手动处理换行符和字符数组
完整示例:安全读取 UTF-8 编码的中文文件
以下代码读取一个 UTF-8 编码的 text.txt(含中文),无乱码:
立即学习“Java免费学习笔记(深入)”;
try (FileInputStream fis = new FileInputStream("text.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line); // 正确输出中文
}
} catch (IOException e) {
e.printStackTrace();
}
⚠️ 注意:JDK 7+ 推荐用 try-with-resources 自动关闭资源;编码名写错(如文件是 GBK 却写 "UTF-8")或文件本身编码不标准,仍会导致乱码。
如何确认文件真实编码?
乱码常源于编码不匹配。可借助工具辅助判断:
- 用编辑器(如 VS Code、Notepad++)打开文件,查看右下角显示的编码格式
- 命令行下用
file -i filename(Linux/macOS)或 PowerShell 的Get-Content加-Encoding尝试不同编码 - Java 中可先用字节流读前几个字节,检查 BOM(如
EF BB BF表示 UTF-8 带 BOM),但多数 UTF-8 文件无 BOM,不能依赖
不复杂但容易忽略:字符流不是“自动防乱码”,而是把解码责任交给你——指定对了编码,中文就读得准。


















