java序列化支持连续写入多个对象,但必须复用同一个objectoutputstream和objectinputstream实例,否则因重复写入流头ac ed导致streamcorruptedexception。

Java 序列化支持将多个对象连续写入同一个 ObjectOutputStream,但必须使用配套的 ObjectInputStream 按顺序读取,且关键在于:**不能每次新建流,否则会因流头冲突导致反序列化失败**。
必须复用同一个 ObjectOutputStream / ObjectInputStream 实例
每次 new 一个 ObjectOutputStream 都会写入一个 2 字节的流协议头(AC ED),而 ObjectInputStream 只在构造时读取并校验一次该头。如果多次 new ObjectOutputStream 写入同一文件或 socket 输出流,会产生多个头,后续的 ObjectInputStream 构造就会抛 StreamCorruptedException。
正确做法是:
- 创建一次
ObjectOutputStream,调用多次writeObject() - 对应地,创建一次
ObjectInputStream,调用多次readObject() - 确保写和读的顺序、次数严格一致(对象类型不要求相同,但数量和顺序必须匹配)
示例:文件中连续写入与读取多个对象
✅ 正确写法(写入):
try (FileOutputStream fos = new FileOutputStream("data.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(new Person("Alice", 30));
oos.writeObject(new ArrayList<string>(Arrays.asList("a", "b")));
oos.writeObject(42);
}</string>
✅ 正确读法(读取):
try (FileInputStream fis = new FileInputStream("data.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
Person p = (Person) ois.readObject(); // 第一个
List<string> list = (List<string>) ois.readObject(); // 第二个
Integer num = (Integer) ois.readObject(); // 第三个
}</string></string>
常见错误及规避方式
❌ 错误:循环中反复 new ObjectOutputStream
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
for (Object obj : objects) {
try (ObjectOutputStream oos = new ObjectOutputStream(fos)) { // ❌ 每次都写头!
oos.writeObject(obj);
}
}
✅ 修复:把流创建提到循环外,仅复用 writeObject
❌ 错误:读取时提前关闭或跳过某个对象,导致后续 readObject() 位置错乱
✅ 建议:用 try-with-resources 管理最外层流;若需条件读取,可用 available() 辅助判断(注意它对网络流不可靠,仅适用于文件/ByteArrayStream)
进阶:跨网络/长连接场景注意事项
在网络传输中(如 Socket),同样要保持单对流实例。特别注意:
- 客户端和服务端必须协商好“写完即 flush”,避免缓冲导致对方阻塞在
readObject() - 建议在每次
writeObject()后调用oos.flush() - 若需中途终止,可约定特殊标记对象(如
null或自定义 EOF 类),避免依赖异常退出 - 不推荐用
reset()——它会重置对象引用表,可能导致反序列化逻辑异常,除非明确需要打破引用共享语义
只要保证流实例唯一、读写成对、顺序一致,Java 原生序列化就能可靠处理多个对象的连续存取。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










