You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向admin_product.bin文件追加对象?关于AppendingObjectOutputStream的疑问

嘿,你找的这个AppendingObjectOutputStream类完全是解决往二进制文件追加序列化对象的正确思路!我来给你拆解清楚它的作用,再补上完整的使用方案~

为什么需要自定义这个输出流?

默认的ObjectOutputStream每次写入文件时,都会先写一段文件头信息。如果直接用普通的流追加写入,文件里就会有多个文件头,后续用ObjectInputStream读取时,会因为解析到多余的文件头而抛出异常。这个自定义类就是专门解决这个问题的!

自定义类代码详解

先把你的代码用代码块整理好:

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class AppendingObjectOutputStream extends ObjectOutputStream {
    public AppendingObjectOutputStream(OutputStream out) throws IOException {
        super(out);
    }

    @Override
    protected void writeStreamHeader() throws IOException {
        // 不写入新的文件头,避免追加时出现多个头导致读取失败
        // 调用reset()让流忘记之前序列化过的对象,避免重复写入对象引用
        reset();
    }
}

关键细节说明:

  • 继承ObjectOutputStream,重写构造方法直接调用父类逻辑
  • 重写writeStreamHeader()方法:不执行默认的写文件头操作,而是调用reset()。reset()的作用是让流重置状态,忘记之前已经序列化过的对象,这样即使同一个对象被多次追加写入,也会完整序列化,而不是只写入对象引用。
如何用它往admin_product.bin追加对象?

给你一个完整的可运行示例,包含写入和读取验证:

import java.io.*;

public class ProductFileHandler {
    // 追加对象到目标文件的方法
    public static void appendProduct(String filePath, Object product) throws IOException {
        // 注意FileOutputStream的第二个参数传true,开启追加模式
        try (OutputStream fileOut = new FileOutputStream(filePath, true);
             AppendingObjectOutputStream appendingOut = new AppendingObjectOutputStream(fileOut)) {
            appendingOut.writeObject(product);
        }
    }

    // 读取文件中所有对象的方法,用于验证追加结果
    public static void readAllProducts(String filePath) throws IOException, ClassNotFoundException {
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath))) {
            while (true) {
                try {
                    Object product = in.readObject();
                    System.out.println("读取到产品: " + product);
                } catch (EOFException e) {
                    // 捕获文件末尾异常,结束读取
                    break;
                }
            }
        }
    }

    public static void main(String[] args) {
        String targetFile = "admin_product.bin";

        // 假设你的产品类是Product,必须实现Serializable接口
        Product laptop = new Product("P001", "游戏笔记本", 7999.99);
        Product phone = new Product("P002", "旗舰手机", 5499.99);

        try {
            // 追加第一个产品
            appendProduct(targetFile, laptop);
            // 追加第二个产品
            appendProduct(targetFile, phone);
            System.out.println("产品追加写入成功!");

            // 验证读取
            System.out.println("\n开始读取文件中的产品:");
            readAllProducts(targetFile);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

// 示例产品类,必须实现Serializable接口才能被序列化
class Product implements Serializable {
    private String productId;
    private String productName;
    private double price;

    public Product(String productId, String productName, double price) {
        this.productId = productId;
        this.productName = productName;
        this.price = price;
    }

    @Override
    public String toString() {
        return String.format("Product{ID='%s', 名称='%s', 价格=%.2f}", productId, productName, price);
    }
}
重要注意事项
  • 要写入的对象类(比如示例中的Product)必须实现Serializable接口,否则会抛出NotSerializableException
  • 一定要给FileOutputStream传入true参数开启追加模式,不然会覆盖原有文件内容
  • 读取时直接用普通的ObjectInputStream即可,它会依次读取所有追加的对象,直到遇到文件末尾的EOFException

内容的提问来源于stack exchange,提问作者Mohammed Arshaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:13:43