调用flush()方法可手动刷新BufferedOutputStream缓冲区,立即将缓存数据写出到底层流并重置count为0;close()会隐式flush并释放资源,但buf数组不被清零或置null。

BufferedOutputStream 没有 public 的 flushBuffer 方法,也不提供直接清理内部字节数组的接口。 它的“缓冲区清理”实际发生在 flush() 或 close() 调用时,本质是把未写入底层流的字节全部写出,并重置缓冲区状态(即清空逻辑,而非显式清零数组内存)。
缓冲区如何“被清理”
BufferedOutputStream 内部维护一个字节数组 buf 和一个计数器 count(记录当前缓冲区中已写入但未刷新的字节数)。所谓“清理”,是指:
-
count被重置为 0,表示缓冲区变为空闲状态; - 已缓存的字节通过调用底层
out.write(buf, 0, count)全部写出; -
buf数组对象本身不会被置为null或逐字节清零(如Arrays.fill(buf, (byte)0)),JVM 不强制擦除内存内容 —— 这是出于性能考虑,且 Java 内存模型不保证敏感数据残留安全。
flush() 是触发清理的正确方式
调用 flush() 会执行标准刷新流程:
- 若
count > 0,将buf[0] 到 buf[count-1]写入底层输出流; - 随后设置
count = 0; - 底层流(如 FileOutputStream)也会被
flush()(如果支持); - 缓冲区数组仍保留在堆上,可继续复用。
为什么不能也不该手动清零 buf 数组
BufferedOutputStream 的 buf 是私有字段,无法直接访问。即使通过反射获取,也不建议做以下操作:
立即学习“Java免费学习笔记(深入)”;
- 手动调用
Arrays.fill(buf, (byte)0):无实际意义,因为后续写入会自然覆盖; - 试图释放或重置数组引用:破坏缓冲区复用机制,影响性能;
- 出于安全目的清零(如写密码):BufferedOutputStream 本就不适合处理敏感数据,应避免用它缓存口令、密钥等 —— 正确做法是不用缓冲,或使用
SecureRandom+ 显式擦除的专用结构。
close() 会隐式 flush 并释放资源
close() 方法内部先调用 flush(),再关闭底层流。此时:
- 缓冲区逻辑清空(
count = 0); - 底层流句柄释放;
- BufferedOutputStream 实例后续不可再用,但
buf数组仍可能存活直到 GC 回收(无主动清零)。


















