FileWriter 是什么?
FileWriter 是 Java I/O 库中的一个类,它属于 java.io 包,它的主要作用是将字符数据写入文件,你可以把它想象成一个“字符写入器”,它专门处理文本(如 .txt, .java, .xml 等文件),而不是二进制数据(如图片、视频)。

FileWriter 的工作原理是:它将写入的字符(char)转换为底层的字节(byte)流,并使用平台的默认字符编码(通常是 UTF-8)进行编码。
基本用法:写入一个新文件
这是最简单的用法,它会创建一个新文件(如果文件不存在)或覆盖一个已存在的文件。
核心步骤:
- 创建
FileWriter对象:指定要写入的文件路径。 - 写入数据:使用
write()方法。 - 关闭流:非常重要! 使用
close()方法关闭FileWriter,以确保所有数据都被刷新到文件中,并释放系统资源。
代码示例:
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExample {
public static void main(String[] args) {
// 定义要写入的文件路径
String filePath = "my-new-file.txt";
// 使用 try-with-resources 语句(推荐)
// 它会自动在 try 块执行完毕后关闭资源,即使发生异常
try (FileWriter writer = new FileWriter(filePath)) {
// 写入一个字符串
writer.write("Hello, FileWriter!\n");
// 写入另一个字符串
writer.write("This is the second line of text.");
System.out.println("文件写入成功!");
} catch (IOException e) {
// 如果发生 I/O 错误(如没有写入权限),会捕获这个异常
System.err.println("写入文件时发生错误: " + e.getMessage());
e.printStackTrace();
}
// writer 会自动被关闭,无需手动调用 writer.close()
}
}
运行结果:
程序执行后,会在项目根目录下创建一个名为 my-new-file.txt 的文件,内容如下:
Hello, FileWriter!
This is the second line of text.
FileWriter 的关键构造函数
FileWriter 提供了几个构造函数,以满足不同的需求:

| 构造函数 | 描述 |
|---|---|
FileWriter(String fileName) |
创建一个 FileWriter 对象,与名为 fileName 的文件关联,如果文件已存在,则其内容将被覆盖。 |
FileWriter(File file) |
创建一个 FileWriter 对象,与 File 对象关联,如果文件已存在,则其内容将被覆盖。 |
FileWriter(String fileName, boolean append) |
创建一个 FileWriter 对象。append 参数为 true 时,数据会被追加到文件末尾,而不是覆盖。 |
FileWriter(File file, boolean append) |
同上,但使用 File 对象作为文件路径。 |
追加模式 vs. 覆盖模式
这是 FileWriter 一个非常重要的特性。
覆盖模式(默认)
如果你只想保留最新的内容,使用默认构造函数或设置 append 为 false。
// 这会先清空文件,然后写入 "New content"
try (FileWriter writer = new FileWriter("my-new-file.txt")) {
writer.write("New content");
}
追加模式
如果你想在文件现有内容的末尾添加新内容,必须使用带 append 参数的构造函数,并将 append 设为 true。
// 这会在 "my-new-file.txt" 文件末尾追加 "Appended content"
try (FileWriter writer = new FileWriter("my-new-file.txt", true)) {
writer.write("\nAppended content"); // 添加一个换行符,让新内容从新的一行开始
}
示例:
假设 my-new-file.txt 原有内容是 Hello, FileWriter!。

// 第一次写入(覆盖)
try (FileWriter writer1 = new FileWriter("my-new-file.txt")) {
writer1.write("This is the first line.");
}
// 第二次写入(追加)
try (FileWriter writer2 = new FileWriter("my-new-file.txt", true)) {
writer2.write("\nThis is the second line.");
}
将是:
This is the first line.
This is the second line.
重要:资源管理与 try-with-resources
在第一个例子中,我们使用了 try-with-resources 语法,这是现代 Java (7+) 推荐的最佳实践。
为什么必须关闭 FileWriter?
当你写入数据时,数据可能首先被存储在内存缓冲区中,而不是立即写入硬盘。close() 方法会执行一个“刷新”(flush)操作,将缓冲区中剩余的所有数据强制写入文件,然后关闭文件流,释放文件句柄等系统资源。
如果不关闭文件,可能会导致:
- 数据丢失:程序异常终止时,缓冲区中的数据可能没有写入文件。
- 资源泄漏:系统无法回收文件句柄,如果长时间运行,可能会耗尽系统资源。
try-with-resources 的优点:
它会自动调用 close() 方法,无论 try �块是正常结束还是抛出异常,这极大地简化了代码,并避免了资源泄漏的风险。
不推荐的旧写法(手动关闭):
FileWriter writer = null;
try {
writer = new FileWriter("my-file.txt");
writer.write("some text");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 必须在 finally 块中关闭,以确保即使发生异常也能执行
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
可以看到,手动关闭非常繁琐且容易出错。
进阶用法:写入字符数组和追加换行符
FileWriter 还提供了其他有用的写入方法。
写入字符数组
char[] charArray = "这是一个字符数组".toCharArray();
try (FileWriter writer = new FileWriter("char-array.txt")) {
writer.write(charArray);
}
追加换行符
在不同操作系统上,换行符可能不同(Windows 是 \r\n,Linux/macOS 是 \n),为了更好的跨平台兼容性,可以使用 System.lineSeparator()。
try (FileWriter writer = new FileWriter("lines.txt")) {
writer.write("第一行" + System.lineSeparator());
writer.write("第二行" + System.lineSeparator());
writer.write("第三行");
}
FileWriter 的局限性
FileWriter 虽然简单,但也有其局限性:
- 性能问题:每次调用
write()方法都可能直接触发 I/O 操作,效率较低,对于大量数据写入,通常会结合BufferedWriter来使用,它会在内存中创建一个缓冲区,减少实际的 I/O 次数,从而大幅提升性能。 - 编码问题:
FileWriter使用的是 JVM 默认的字符编码,这在不同环境下可能会导致乱码,如果你的系统默认编码是 GBK,但你想写入 UTF-8 编码的文件,就会出现问题。
如何解决编码问题?
可以使用 OutputStreamWriter 来包装 FileOutputStream,并明确指定字符编码。
import java.io.*;
import java.nio.charset.StandardCharsets; // 推荐使用 StandardCharsets 枚举
public class FileWriterWithEncoding {
public static void main(String[] args) {
String filePath = "encoded-file.txt";
String text = "你好,世界!Hello, World!";
// 使用 try-with-resources 确保 OutputStreamWriter 和 FileOutputStream 都被关闭
try (FileOutputStream fos = new FileOutputStream(filePath);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
FileWriter writer = new FileWriter(osw)) { // 注意:这里 FileWriter 是多余的,直接用 OutputStreamWriter 即可
// 正确的写法是直接使用 OutputStreamWriter
// osw.write(text);
System.out.println("文件以 UTF-8 编码写入成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
更简洁的写法(直接使用 OutputStreamWriter):
// 正确且推荐的做法
try (OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("encoded-file.txt"), StandardCharsets.UTF_8)) {
osw.write("你好,世界!Hello, World!");
System.out.println("文件以 UTF-8 编码写入成功!");
} catch (IOException e) {
e.printStackTrace();
}
