根本原因是字节序列与解码方式不匹配:Java以UTF-8写入,而Windows/Excel默认用GBK解析无BOM的文件,导致乱码;解决关键是写入UTF-8时必须前置BOM(\uFEFF),并显式指定编码读写,禁用依赖系统默认编码的FileWriter/FileReader。

Java 处理 CSV 文件时出现中文乱码,根本原因不是“写错了字符”,而是字节序列和解码方式不匹配。Windows 系统默认用 GBK 解析无标记文件,而你写的却是 UTF-8 字节——Excel 打开时自然显示成“浣犲ソ”。关键不在“怎么写”,而在“怎么写得让别人(尤其是 Excel)认得出是 UTF-8”。
导出 CSV:必须用 OutputStreamWriter + UTF-8 + BOM
别用 FileWriter(String),它走系统默认编码(Windows 是 GBK),写出来就是错的字节。正确做法是绕过 FileWriter,用底层流显式控制:
- 用
FileOutputStream打开文件输出流 - 套一层
OutputStreamWriter,传入StandardCharsets.UTF_8 - 写入前先写入 BOM(
"\uFEFF"),这是 Excel 唯一能稳定识别 UTF-8 的信号 - 再写表头、数据行,最后关闭资源(推荐 try-with-resources)
导入 CSV:读取时必须指定 UTF-8,不能依赖 FileReader
FileReader 同样走系统默认编码,读 UTF-8 文件必乱码。正确方式是:
- 用
FileInputStream获取原始字节流 - 套
InputStreamReader,明确传StandardCharsets.UTF_8 - 再包一层
BufferedReader提高效率 - 若用 Apache Commons CSV 或 Hutool CsvReader,构造时务必传入 UTF-8 编码参数,不要用无参构造
验证与排查:别猜,要实测
乱码问题常因环节脱节导致,需逐层确认:
立即学习“Java免费学习笔记(深入)”;
- 用记事本或 VS Code 查看 CSV 文件“另存为”时的编码选项,确认真实保存格式是 UTF-8(带 BOM 更稳妥)
- 在 Linux/macOS 下运行
file -i your.csv,看输出是否为charset=utf-8 - 如果用 JMeter 或第三方工具读取,检查其组件里是否有“File Encoding”设置项,必须填
UTF-8 - 避免依赖
-Dfile.encoding=UTF-8,该参数只影响 JVM 内部,对 Excel、JMeter 等外部程序无效
工具库使用注意:Hutool、Commons CSV 都要设编码
这些封装库默认不强制 UTF-8,不显式指定就会掉进系统编码陷阱:
- Hutool 的
CsvWriter构造时传CharsetUtil.CHARSET_UTF_8 - Commons CSV 的
CsvParser要用Files.newBufferedReader(path, StandardCharsets.UTF_8)创建 reader - 自己封装的工具方法,把
charsetName参数设为必填,不要给默认值(如 “GBK”)


















