FileWriter 文件字符写入
有些人写日志用 FileWriter,有些人用 OutputStreamWriter。
表面上看,FileWriter 短了一截。但当你的应用跑在 Windows 服务器上,日志文件用 GBK 编码;而另一套 Linux 系统用 UTF-8 读取时——你就会明白那几行代码省的是什么。
基本用法
写入模式
java
// 覆盖模式(默认)
FileWriter fw = new FileWriter("output.txt");
// 追加模式
FileWriter fw = new FileWriter("output.txt", true);
// File 对象
FileWriter fw = new FileWriter(new File("output.txt"));
// File 对象 + 追加模式
FileWriter fw = new FileWriter(new File("output.txt"), true);第二个参数 true 表示追加模式,false(默认)是覆盖模式。
写入操作
java
// 单字符写入
try (FileWriter fw = new FileWriter("output.txt")) {
fw.write(65); // 写入字符 'A'
fw.write('\n');
fw.write("你好 Java"); // 直接写字符串
}
// 字符数组写入
try (FileWriter fw = new FileWriter("output.txt")) {
char[] chars = {'H', 'e', 'l', 'l', 'o'};
fw.write(chars);
fw.write("\n");
fw.write(chars, 0, 3); // 写前 3 个字符:Hel
}FileWriter 的问题:无法指定编码
和 FileReader 一样,FileWriter 有一个致命缺陷:不能指定字符编码。
java
// ❌ 问题:依赖平台默认编码
FileWriter fw = new FileWriter("output.txt");
// Windows 用 GBK 写入,macOS 用 UTF-8 读取 → 乱码
// ✅ 正确:用 OutputStreamWriter + 指定编码
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8))) {
writer.write("你好 Java");
}追加写入的正确姿势
java
// 追加模式:保留原有内容
try (FileWriter fw = new FileWriter("log.txt", true)) {
fw.write("New log entry at " + System.currentTimeMillis() + "\n");
}
// 多次运行,log.txt 的内容会越来越多BufferedWriter 的加持
java
// BufferedWriter:加缓冲 + newLine()
try (
BufferedWriter writer = new BufferedWriter(
new FileWriter("output.txt"))
) {
writer.write("第一行");
writer.newLine(); // 平台无关的换行符
writer.write("第二行");
writer.newLine();
writer.flush();
}
// newLine() 自动适配:Windows → \r\n,Linux/macOS → \nnewLine() 的作用:
| 平台 | newLine() 写入 | write("\n") 写入 |
|---|---|---|
| Windows | \r\n | \n(不一致!) |
| Linux / macOS | \n | \n(一致) |
对比:FileWriter vs OutputStreamWriter
| 特性 | FileWriter | OutputStreamWriter |
|---|---|---|
| 指定编码 | ❌ 不支持 | ✅ 支持 |
| 内部实现 | 直接用默认编码 | 包装字节流 + 编码器 |
| 适用场景 | 纯英文、快速原型 | 生产环境、多语言 |
java
// ❌ FileWriter:不能指定编码
try (FileWriter fw = new FileWriter("output.txt")) {
fw.write("你好");
} // 依赖系统默认编码,可能乱码
// ✅ OutputStreamWriter:可以指定编码
try (
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8))
) {
writer.write("你好");
}
// ✅ JDK 11+ 最简写法
Files.writeString(Path.of("output.txt"), "你好", StandardCharsets.UTF_8);常见问题
目录不存在
java
// ❌ 目录不存在会抛异常
new FileWriter("/nonexistent/dir/file.txt");
// ✅ 先创建目录
File file = new File("/nonexistent/dir/file.txt");
file.getParentFile().mkdirs();
try (FileWriter fw = new FileWriter(file)) {
fw.write("content");
}write() vs append()
java
// 效果相同,但 append() 返回 Writer,支持链式调用
fw.write("Hello");
fw.append("Hello").append(" ").append("World");记住这个原则:
FileWriter 写英文,OutputStreamWriter 写世界。 生产环境永远指定编码,永远用 BufferedWriter。
