用bufferedoutputstream包裹fileoutputstream再传给objectoutputstream是最常用有效的加速方式,通过8kb缓冲区合并多次小写为少量大写,减少系统调用,提升序列化写入速度。

直接用 ObjectOutputStream 包裹 BufferedOutputStream 是最常用且有效的加速方式——它把零散的小写操作攒成一批,减少系统调用次数,从而显著提升序列化写入速度。
为什么 BufferedOutputStream 能加速 ObjectOutputStream
默认的 ObjectOutputStream 直接连 FileOutputStream,每次写少量字节(比如对象头、字段标记)都会触发一次底层系统调用,开销大。而 BufferedOutputStream 在内存中维护一个默认 8KB 的缓冲区,只有缓冲区满或显式 flush() 时才真正写入磁盘。这样就把几十次小写合并为几次大写,I/O 效率明显上升。
标准写法:BufferedOutputStream 套在 FileOutputStream 外层
这是推荐且安全的做法,结构清晰、兼容性好:
- 先创建
FileOutputStream,指向目标文件 - 用它构造
BufferedOutputStream - 再把
BufferedOutputStream传给ObjectOutputStream构造器 - 调用
writeObject(),最后按顺序关闭(ObjectOutputStream关闭会自动级联关闭下层流)
示例代码:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
try (FileOutputStream fos = new FileOutputStream("data.ser");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(myObject);
} catch (IOException e) {
e.printStackTrace();
}
不推荐但可行的变体:RandomAccessFile + FileOutputStream
有资料提到用 RandomAccessFile 获取文件描述符再构造 FileOutputStream,理论上可绕过部分 FileOutputStream 的同步开销。但实际收益有限,且增加复杂度和出错风险(如文件描述符管理不当易泄漏),JDK 8 及以后版本已优化了标准路径,一般无需采用。
进阶提速:结合 Kryo 或 Protobuf 替代原生序列化
如果性能是核心诉求,Java 原生序列化本身较重(含类信息、校验、反射开销)。此时可考虑:
- 用
Kryo(需注册类,不依赖Serializable)替代ObjectOutputStream,序列化体积更小、速度更快 - 将
Kryo输出写入BufferedOutputStream,同样享受缓冲收益 - 对高频读写的场景,还可预分配缓冲区大小(如
new BufferedOutputStream(fos, 64 * 1024)),避免频繁扩容
注意:Kryo 等第三方方案需引入额外依赖,且反序列化需保证类结构兼容,适用于可控环境。
不复杂但容易忽略:缓冲流必须正确关闭,否则最后一块数据可能滞留在内存中未写出;使用 try-with-resources 是最稳妥的方式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










