核心是用内存缓冲减少磁盘I/O次数:BufferedOutputStream通过8KB默认缓冲区聚合写操作,仅在填满、flush()或close()时触发系统调用,避免FileOutputStream每次write()都直写磁盘;10MB文件实测从320ms降至85ms,小数据高频写提速5–10倍;需正确初始化(try-with-resources、大文件调大缓冲区)、避免不close/频繁flush/线程不安全等坑;常规场景首选,GB级或异步需求再考虑NIO。

核心就一条:用内存缓冲代替频繁磁盘写入。BufferedOutputStream 不是让单次写更快,而是大幅减少真正触达磁盘的次数——这才是提速的关键。
为什么它比 FileOutputStream 快?
FileOutputStream 每调用一次 write(),基本就触发一次系统调用,数据直奔磁盘;而 BufferedOutputStream 在内存里维护一个字节数组(默认 8KB),只在三种情况下才把整块数据推给底层流:缓冲区填满、显式调用 flush()、或 close()。一次系统调用写 8KB,远好过 8000 次调用写 1 字节。
- 小数据高频写(比如循环写短字符串)时,性能差距常达 5–10 倍
- 10MB 文件写入实测:FileOutputStream 约 320ms,BufferedOutputStream 约 85ms
- 提速本质不是“加速磁盘”,而是“少找磁盘”
怎么初始化才真正有效?
别只套个壳,得配得对:
- 用
try-with-resources包裹,确保自动close()—— 这会隐式flush(),避免数据滞留 - 大文件(如 >100MB)建议手动设缓冲区为 64KB~256KB,例如
new BufferedOutputStream(fos, 131072) - 底层用
FileOutputStream时,不要让它自己再缓——Java 8+ 默认已禁用其内部缓冲,但老版本或自定义场景下要留意 - 绝对不要嵌套两层
BufferedOutputStream,纯属白加开销
最容易踩的三个坑
缓冲带来便利,也埋了静默丢数据的雷:
立即学习“Java免费学习笔记(深入)”;
- 不 close / 不 flush:程序崩溃或提前退出,最后几 KB 还卡在内存里,磁盘上永远没这数据
- 每写一行就 flush():等于把缓冲流当裸流用,性能可能比 FileOutputStream 还差
- 当成线程安全工具:它本身不是线程安全的,多线程并发写同一实例必须加锁或改用其他方案
要不要换 NIO 或内存映射?
BufferedOutputStream 对绝大多数常规写入(日志、导出、配置生成等)已足够高效。只有当你遇到以下情况,才需考虑升级:
- 单文件超 GB 级,且追求极致吞吐(此时
FileChannel.map()+MappedByteBuffer可能更优) - 需要异步非阻塞写(配合
AsynchronousFileChannel) - 已有 NIO 流水线,统一技术栈更利于维护
日常开发中,写法简洁、行为确定、兼容性好,BufferedOutputStream 仍是首选。


















