1. 概述
本文深入解析 Java 标准库中的 FileWriter
类,它位于 java.io
包中,是处理字符文件写入的常用工具类之一。
虽然功能看似简单,但在实际开发中如果不注意编码、资源管理等问题,很容易踩坑。尤其在跨平台或涉及中文字符时,稍不注意就会出现乱码或文件写入失败。
2. FileWriter 简介
✅ FileWriter
是 OutputStreamWriter
的子类,专用于向文件写入字符数据。
❌ 它本身不提供新的写入方法,所有操作都继承自 Writer
和 OutputStreamWriter
。
在 Java 11 之前,FileWriter
只能使用默认字符集(通常是系统平台默认,如 Windows 的 GBK,Linux/Unix 的 UTF-8)和固定大小的缓冲区(8192 字节)。
⚠️ 从 Java 11 开始,新增了支持指定 Charset
的构造函数,解决了长期以来无法自定义编码的问题,但缓冲区大小仍不可调,固定为 8192。
2.1 创建 FileWriter 实例
在 Java 11 之前,FileWriter
提供了 5 个构造函数:
public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}
public FileWriter(String fileName, boolean append) throws IOException {
super(new FileOutputStream(fileName, append));
}
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
}
Java 11 新增了 4 个支持指定字符集的构造函数:
public FileWriter(String fileName, Charset charset) throws IOException {
super(new FileOutputStream(fileName), charset);
}
public FileWriter(String fileName, Charset charset, boolean append) throws IOException {
super(new FileOutputStream(fileName, append), charset);
}
public FileWriter(File file, Charset charset) throws IOException {
super(new FileOutputStream(file), charset);
}
public FileWriter(File file, Charset charset, boolean append) throws IOException {
super(new FileOutputStream(file, append), charset);
}
📌 关键点总结:
- 所有构造函数底层都依赖
FileOutputStream
append
参数控制是否追加写入(true
表示追加)- Java 11 前无法指定编码,容易导致乱码问题(尤其是中文)
- 使用
Charset
构造函数可避免平台默认编码带来的兼容性问题
2.2 写入字符串到文件
使用 FileWriter
写入字符串非常简单,推荐结合 try-with-resources 自动管理资源:
try (FileWriter fileWriter = new FileWriter("src/test/resources/FileWriterTest.txt")) {
fileWriter.write("Hello Folks!");
}
执行后,文件内容为:
Hello Folks!
📌 注意事项:
- ✅
FileWriter
实现了AutoCloseable
,使用 try-with-resources 可自动关闭流,避免资源泄漏 - ⚠️ 不保证文件一定能创建成功,具体行为依赖底层操作系统。例如某些系统可能因权限问题导致创建失败
- ❌ 某些平台(如 Windows)对文件独占锁较严格,同一时间只能有一个
FileWriter
打开该文件,否则会抛出IOException
💡 建议:生产环境务必捕获
IOException
,并做好异常日志记录。
2.3 向文件追加内容
很多时候我们不希望覆盖原文件,而是追加内容。这时只需将 append
参数设为 true
:
try (FileWriter fileWriter = new FileWriter("src/test/resources/FileWriterTest.txt", true)) {
fileWriter.write("Hello Folks Again!");
}
执行后,文件内容变为:
Hello Folks!Hello Folks Again!
📌 追加模式要点:
- 第二个参数
true
表示以追加方式打开文件 - 如果文件不存在,仍会自动创建
- 多次追加不会自动换行,如需换行需手动添加
\n
或使用newLine()
方法
💡 小技巧:若要换行追加,可这样写:
fileWriter.write("Hello Folks Again!\n");
3. 总结
FileWriter
是一个简单粗暴的字符文件写入工具,适合快速实现文本写入需求。但在实际项目中需要注意以下几点:
- ✅ Java 11+ 推荐使用带
Charset
的构造函数,明确指定编码(如StandardCharsets.UTF_8
),避免乱码 - ✅ 必须使用 try-with-resources 管理资源
- ⚠️ 注意平台兼容性问题,尤其是文件锁和默认编码
- 🚫 不适用于大文件写入(无缓冲优化),建议结合
BufferedWriter
使用
示例完整代码已托管至 GitHub: https://github.com/baeldung/core-java-modules/tree/master/core-java-io-apis
对于更复杂的 I/O 操作,建议考虑 Files.write()
或 BufferedWriter
配合 OutputStreamWriter
的方式,灵活性和性能更优。