bufferedoutputstream在缓冲区写满(count == buf.length)时自动调用flushbuffer()刷盘,是其提升io性能的核心机制;它通过8192字节buf暂存数据、count跟踪已写入字节数,并在满、close或显式flush时触发刷新,避免频繁系统调用。

BufferedOutputStream 在写满缓冲区时会自动刷盘,这是它提升 IO 性能的核心机制,不需要手动 flush 每次写入。
缓冲区结构与 count 的作用
BufferedOutputStream 内部维护一个默认 8192 字节的字节数组 buf,以及一个 protected int count 字段,表示当前缓冲区中已写入的有效字节数(范围始终是 0 到 buf.length)。每次 write() 调用都会把数据拷贝进 buf,并更新 count。当 count 达到 buf.length(即缓冲区“写满”),就触发自动刷新。
自动刷盘的触发时机
- 缓冲区写满:count == buf.length 时,内部调用 flushBuffer(),将整个 buf 写入底层 OutputStream,并重置 count = 0
- 流关闭时:close() 方法内部会先 flush(),确保剩余未满的数据也落盘
- 显式调用 flush():强制刷新当前缓冲区内容,无论是否写满
源码层面的关键逻辑
在 BufferedOutputStream 的 write(byte[], int, int) 方法中,会逐段检查剩余空间:
- 若单次写入长度 ≤ 剩余空间(buf.length - count),直接复制进 buf,count += len
- 若写入长度超过剩余空间,先填满当前缓冲区并 flushBuffer(),再将剩余数据直接写到底层流(绕过缓冲)或分批填入新缓冲
这种设计保证了“满即刷”,避免了小数据频繁触发 IO,也规避了因忘记 flush 导致数据丢失的风险。
为什么不用每次都 flush
每 write 后调用 flush() 实际上让缓冲区失效:它强制将当前缓冲内容写出,再清空缓冲区——相当于退化成无缓冲的 FileOutputStream,还额外增加了方法调用和同步开销。实测表明,仅靠自动满刷 + close 刷尾,性能可达手动 flush 的 3~5 倍以上。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











