BufferedWriter 比 FileWriter 快因默认8192字节缓冲减少系统调用;需手动flush()确保数据落盘;换行用newLine()而非"\n";必须显式指定UTF_8编码并用try-with-resources管理资源。

BufferedWriter 为什么比 FileWriter 快
因为 FileWriter 每次调用 write() 都触发一次系统调用,而 BufferedWriter 默认用 8192 字节缓冲区暂存数据,等满、flush() 或 close() 时才批量落盘。一次系统调用耗时约几百纳秒,反复调用在写入 10 万行时可能慢几十倍。
但缓冲区不是越大越好:new BufferedWriter(writer, 65536) 在内存紧张或崩溃风险高时反而得不偿失。默认值够用,除非你明确知道单行常超 4KB——这时可设为 16384 或 32768,避免频繁刷盘。
必须手动 flush() 的三个关键时机
BufferedWriter 不会在缓冲区未满时自动刷盘,JVM 退出也不会帮你兜底。常见“文件只写了一半”就是漏了这步。
- 循环中写入中途需确保内容已落盘(如日志轮转、断点续传)→ 立即调用
bw.flush() - 全部写完后、关闭前 → 必须先
bw.flush(),再bw.close();仅close()虽会尝试 flush,但若抛出异常,这步就被跳过 - 捕获到
IOException后还想继续写 → 别直接重试,先bw.flush()看是否能清空脏缓冲区,否则后续写可能持续失败
换行符和批量写入的坑
手写 "\n" 在 Windows 上会导致文本编辑器显示为一行,因为真实换行符是 "\r\n"。最安全的是用 bw.newLine(),它内部调用 System.lineSeparator()。
别在循环里拼大字符串再写,例如:
String all = String.join("\n", lines);
bw.write(all);
这既跨平台错乱(没用 System.lineSeparator()),又失去缓冲优势(一次性占满堆内存)。应改为:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
for (String line : lines) {
bw.write(line);
bw.newLine();
}
更别用 bw.append(str).append("\n") —— 每次 append() 都检查缓冲区容量,开销比 write() 大。
编码与资源管理的硬性要求
性能瓶颈常不在 BufferedWriter 本身,而在底层:用 FileWriter 默认编码(平台相关)或漏设 StandardCharsets.UTF_8,会导致隐式编码转换拖慢速度;用 OutputStreamWriter 却没传 charset,也会掉进陷阱。
务必用 try-with-resources,且显式指定编码:
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"),
StandardCharsets.UTF_8))) {
// 写入逻辑
}
不用 FileWriter 包装器——它不支持指定编码,且构造时若传 String 路径,无法控制 Charset。
真正容易被忽略的是:缓冲区大小、flush() 时机、换行符来源、编码一致性,这四点任何一个出错,都可能让性能优化归零,甚至引发数据丢失或乱码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










