bufferedwriter 比 filewriter 快是因为其使用内存缓冲区(默认8192字节)批量写入,减少系统调用次数;但需手动 flush() 保证数据落盘,且注意换行符、编码、线程安全等问题。

BufferedWriter 为什么比 FileWriter 快
因为 FileWriter 每次 write() 都直接触发系统调用,而 BufferedWriter 先把数据攒在内存缓冲区(默认 8192 字节),等缓冲区满、调用 flush() 或 close() 时才批量写入磁盘。一次系统调用 ≈ 几百纳秒,反复调用可能拖慢几十倍。
但缓冲区不是越大越好:过大会增加内存占用,且在程序崩溃时丢失更多未刷出的数据。
- 默认缓冲区大小够大多数场景,别急着改
new BufferedWriter(writer, size) - 如果单行超 4KB,建议把缓冲区设为
16384或32768,避免频繁 flush - 别用
BufferedWriter写极小量数据(比如每行就几个字节、总共不到 10 行)——反而多一层封装开销
必须手动 flush() 的三个典型时刻
BufferedWriter 不会在写满前自动刷盘,也不保证 JVM 退出时帮你刷完。常见“文件写了一半就没了”就是卡在这儿。
- 循环写入中途需要确保内容已落盘(比如日志轮转、断点续传)→ 立即调用
bw.flush() - 写完全部内容后、关闭前 → 必须
bw.flush(),再bw.close();只close()虽然会 flush,但异常抛出会跳过这步 - 捕获到
IOException后还想继续写 → 别直接重试,先bw.flush()看是否能恢复,否则缓冲区可能已脏
错误示例:bw.write("data"); throw new RuntimeException(); → 缓冲区数据永久丢失。
换行符陷阱:lineSeparator() 不是 \n
用 bw.newLine() 是最安全的,它调用 System.lineSeparator(),返回当前平台真实换行符(Windows 是 \r\n,Linux/macOS 是 \n)。手写 "\n" 在 Windows 上会导致文本编辑器显示为一行。
- 不要用
bw.write("\n")替代bw.newLine() - 批量写字符串数组时,别拼接
String.join("\n", lines)再 write —— 这样跨平台错乱,且失去缓冲优势 - 如果必须拼接,用
String.join(System.lineSeparator(), lines)
实操建议:循环中优先 bw.write(line); bw.newLine();,而不是攒大字符串。
性能瓶颈常不在 BufferedWriter 本身
当写入速度上不去,别只盯着 BufferedWriter 参数调优。真正卡住的往往是磁盘 I/O、编码转换或锁竞争。
- 确认底层
FileWriter用的是UTF-8(默认),别用GBK等慢编码;更别用OutputStreamWriter+FileOutputStream却漏设StandardCharsets.UTF_8 - 避免在循环里反复
bw.append(str).append("\n")——append()每次都检查缓冲区,不如write()+newLine() - 多线程共用一个
BufferedWriter?别干这事。要么加锁,要么每个线程独占实例(推荐)
最常被忽略的一点:BufferedWriter 再快,也快不过把内容先写进 StringBuilder,最后一次性 bw.write(sb.toString()) —— 但这只适合总数据量可控(










