如何向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
相关产品推荐
相关产品推荐

