应避免直接使用filewriter处理中文,改用outputstreamwriter配合指定utf-8编码的fileoutputstream。因filewriter依赖平台默认编码(如windows的gbk),与utf-8源码不匹配会导致乱码;推荐用files.write或outputstreamwriter+bufferedwriter确保编码一致。

FileWriter 默认使用平台默认编码(如 Windows 的 GBK),而中文文本通常需 UTF-8 编码,直接用 FileWriter 写入中文极易出现乱码甚至报错。根本解决方法是**避免直接使用 FileWriter 处理中文,改用 OutputStreamWriter 配合指定 UTF-8 编码的 FileOutputStream**。
为什么 FileWriter 会乱码
FileWriter 是 InputStreamReader 的字符流封装,内部调用系统默认编码。Java 9+ 虽默认 UTF-8,但旧版本和部分 Windows 环境仍为 GBK 或 ISO-8859-1。若源码是 UTF-8 编码,而 FileWriter 用 GBK 写入,字节序列错位,就会产生??或异常。
正确写法:用 OutputStreamWriter 指定 UTF-8
这是最可靠、兼容性最好的方式:
- 用 FileOutputStream 打开文件输出流
- 用 OutputStreamWriter 包装它,并显式传入 "UTF-8" 编码名
- 再套一层 BufferedWriter 提升性能(可选但推荐)
示例代码:
try (FileOutputStream fos = new FileOutputStream("data.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw)) {
bw.write("你好,世界!");
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
替代方案:使用 Files.write(Java 7+ 推荐)
更简洁安全,自动处理编码和资源关闭:
- 用 Paths.get() 获取路径
- 用 Files.write() 直接写字符串列表,指定 StandardCharsets.UTF_8
- 支持追加(StandardOpenOption.APPEND)、覆盖等选项
示例:
List<string> lines = Arrays.asList("第一行", "第二行");
Files.write(Paths.get("data.txt"), lines, StandardCharsets.UTF_8);</string>
注意事项与常见误区
以下操作容易引发问题,需特别留意:
- 不要依赖 FileWriter(String) 构造函数——它不接受编码参数,无法控制编码
- IDE 文件编码要和代码中指定编码一致(如 IntelliJ / VS Code 中确认文件保存为 UTF-8,且无 BOM)
- 读取时也要用相同编码:写用 UTF-8,读也必须用 UTF-8 的 InputStreamReader 或 Files.readAllLines
- 若必须用 FileWriter(如某些老框架限制),可在 JVM 启动时加参数 -Dfile.encoding=UTF-8,但该方式全局生效、不可靠,不推荐










