关键是从源头确保UTF-8解码:文件须UTF-8保存,InputStreamReader显式用StandardCharsets.UTF_8;验证真实编码,禁用无参构造;搭配BufferedReader与try-with-resources;避免提前读取、混用FileReader或中途换编码。

关键不是“转换”,而是从源头确保字节流用 UTF-8 规则解码。只要文件本身是 UTF-8 编码保存的,且 InputStreamReader 显式按 UTF-8 解析,中文就能原样还原。
确认文件真实编码
乱码第一步就错在“猜编码”。不能默认文件是 UTF-8,得验证:
- 用编辑器(如 VS Code、Notepad++)打开文件,右下角看实际编码标识
- 命令行可用
file -i filename(Linux/macOS)或chcp+ 查看记事本另存为选项(Windows) - 若文件由别人提供,直接问对方保存时选的是什么编码
用 StandardCharsets.UTF_8 构造 InputStreamReader
绝不用无参构造,也别传字符串 "utf8" 或 "UTF8" —— 容易拼错或触发异常:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ✅ 推荐写法:
new InputStreamReader(is, StandardCharsets.UTF_8)(类型安全、不抛异常) - ⚠️ 可用但次选:
new InputStreamReader(is, "UTF-8")(注意连字符和大写) - ❌ 禁止写法:
new InputStreamReader(is)(依赖系统默认,Windows 是 GBK,必乱码)
搭配 BufferedReader 并用 try-with-resources
InputStreamReader 本身只做解码,不缓冲、不支持按行读。单独用它效率低、易出错:
立即学习“Java免费学习笔记(深入)”;
- 包装成
BufferedReader,方便readLine(),性能更好 - 用 try-with-resources 自动关闭所有层:底层 InputStream → InputStreamReader → BufferedReader
- 只需调
br.close(),内部会级联关闭,无需手动关 isr 或 is
避开常见陷阱
很多看似能跑通的代码,其实埋着乱码隐患:
- 别提前读取 InputStream:创建 InputStreamReader 前,不能调
is.read()或is.mark(),否则开头字节丢失,解码错位 - 别混用 FileReader:它没有显式编码参数(Java 11+ 虽支持,但旧项目仍普遍),默认用系统编码,不可靠
- 别在不同环节换编码:文件用 UTF-8 写,就读时也必须用 UTF-8;写入控制台前再转一次编码,反而二次损坏

















