使用 BufferedOutputStream 写二进制文件的核心是减少系统调用——通过内部缓冲区暂存数据,攒够或显式刷新时才写入磁盘;需包装现有 OutputStream,推荐批量写、合理设置缓冲区大小,并用 try-with-resources 确保关闭。

用 BufferedOutputStream 写二进制文件,核心是减少底层系统调用次数——它通过内部缓冲区暂存数据,等攒够或显式刷新时才真正写入磁盘。
创建带缓冲的输出流
不能直接 new,必须包装一个已存在的 OutputStream(如 FileOutputStream):
- 缓冲区大小默认是 8192 字节,一般够用;若写大量小块数据,可手动指定更大值(如
new BufferedOutputStream(fos, 64 * 1024)) - 务必用 try-with-resources 确保流被正确关闭,否则缓冲区里未刷出的数据会丢失
写入数据的推荐方式
优先使用 write(byte[] b, int off, int len) 批量写,避免单字节写(write(int b))——后者每调一次都可能触发缓冲区检查,效率低:
- 读取源数据时尽量按缓冲区大小对齐(如每次读 8KB),再整块写入
- 如果只有零散小数组,可先合并到一个大缓冲区再写,比逐个
write()快得多
刷新与关闭的时机
缓冲区不会自动实时落盘,需主动控制:
立即学习“Java免费学习笔记(深入)”;
- 写完关键数据后调用
flush(),确保立即持久化(例如日志写入、断点续传场景) - 正常流程中,
close()会自动调用flush(),所以只要保证关闭,就不会丢数据 - 不要在循环内频繁
flush(),这会让缓冲失去意义
常见坑与规避方法
实际用的时候容易踩几个点:
- 忘记关闭流:用 try-with-resources 最稳妥,避免资源泄漏和数据丢失
- 缓冲区太小又写太碎:比如每次只写 1 字节,性能可能比不用缓冲还差
- 误以为 flush() 是必须的:普通文件写入只需关流;只有需要“立刻可见”时才额外 flush


















