必须显式指定编码格式,否则依赖平台默认编码(如Windows用GBK、Linux/macOS用UTF-8)极易乱码;应使用InputStreamReader包装FileInputStream并传入StandardCharsets.UTF_8等明确编码,再套BufferedReader提升效率。

Java 中读取文本文件时,必须显式指定编码格式,否则会使用平台默认编码(如 Windows 上常为 GBK,Linux/macOS 上多为 UTF-8),极易导致中文乱码。核心方法是用 InputStreamReader 包装字节流,并传入明确的字符集;再配合 BufferedReader 提升读取效率。
用 InputStreamReader + FileInputStream 指定编码读文件
这是最基础也最可控的方式,适用于任意本地文件路径:
- 先用
FileInputStream打开文件,得到原始字节流 - 再用
InputStreamReader包装它,并传入标准编码名(如"UTF-8"或"GBK")——注意拼写必须准确,"utf8"会抛UnsupportedEncodingException - 推荐使用
StandardCharsets.UTF_8(Java 7+),类型安全、无字符串拼写风险 - 务必套上
BufferedReader,避免每次readLine()都触发底层 I/O
示例代码:
try (FileInputStream fis = new FileInputStream("data.txt");InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
从 classpath(含 JAR 包)中读资源并指定编码
当文本文件被打包进 JAR 或放在 classpath 下(如 src/main/resources/config.txt),不能用文件路径,得用资源加载方式:
- 调用
Class.getResourceAsStream("/config.txt")(以/开头表示从 classpath 根开始找)或getClass().getResourceAsStream("config.txt")(相对当前类所在包) - 返回
null表示资源未找到,需检查路径是否正确、文件是否真在 classpath 中、JAR 是否包含该资源 - 后续仍用
InputStreamReader+ 编码包装,逻辑与上一节一致
常见错误:误用 new File("config.txt") —— 这在 JAR 环境下会找不到文件。
验证和选择合适的编码格式
若不确定文件真实编码,可尝试以下策略:
- 查看文件是否带 BOM:UTF-8 文件开头若有
EF BB BF三字节,基本可确认;GBK/GB2312 通常无 BOM - 用工具辅助判断:如开源库
juniversalchardet或cpdetector,基于字节统计推测编码(但非 100% 准确) - 简单试探法:先试
UTF-8,若乱码再试GBK;中文环境下的旧文件大概率是 GBK - 开发阶段可在 IDE(如 IntelliJ)中统一设置项目编码为 UTF-8,并确保所有文本文件保存时也选 UTF-8
避免乱码的其他关键点
编码问题常不只出在读取端:
- 控制台输出乱码?检查终端或 IDE 的控制台编码设置(如 IntelliJ → File → Settings → Editor → File Encodings → Console Encoding)
- 写文件时也要指定编码:用
OutputStreamWriter替代FileWriter,否则默认用平台编码写入 - 不要依赖
FileReader/FileWriter:它们不接受编码参数,内部硬编码使用平台默认编码,不可控 - 处理大文件时,保持
BufferedReader的缓冲区默认大小即可,无需手动调优
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











