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

Java数组序列化追加存储与反序列化读取方案咨询

Java序列化对象追加到文件及读取所有对象的实现方案

一、问题分析

你的原代码存在两个核心问题:

  1. 使用FileOutputStream时未开启追加模式,每次调用都会覆盖原有文件内容;
  2. 直接用ObjectOutputStream追加写入时,每次都会写入序列化头部,导致后续读取时抛出反序列化异常。

下面给出针对性的修改方案,实现数据追加和完整读取。

二、写入(追加)实现

1. 自定义可追加的对象输出流

需要自定义一个输出流,避免重复写入序列化头部:

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

public class AppendableObjectOutputStream extends ObjectOutputStream {

    public AppendableObjectOutputStream(OutputStream out) throws IOException {
        super(out);
    }

    @Override
    protected void writeStreamHeader() throws IOException {
        // 追加模式下跳过序列化头部写入,仅保留第一次写入的头部
        reset();
    }
}

2. 修改写入方法

开启文件追加模式,并根据文件是否已有内容选择对应的输出流:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public static void order_history(String name, int keychain_count) {
    String[][] newArray = {{name, String.valueOf(keychain_count)}};
    File tempFile = new File("t.tmp");
    boolean fileHasContent = tempFile.exists() && tempFile.length() > 0;

    // 使用try-with-resources自动关闭流,避免资源泄漏
    try (FileOutputStream fos = new FileOutputStream(tempFile, true);
         ObjectOutputStream oos = fileHasContent ? new AppendableObjectOutputStream(fos) : new ObjectOutputStream(fos)) {
        oos.writeObject(newArray);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

三、读取所有对象实现

通过循环读取文件中的所有序列化对象,直到文件末尾:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

public static List<String[][]> readAllOrderHistory() {
    List<String[][]> historyList = new ArrayList<>();

    try (FileInputStream fis = new FileInputStream("t.tmp");
         ObjectInputStream ois = new ObjectInputStream(fis)) {
        while (true) {
            try {
                // 读取单个序列化对象并转换为目标类型
                String[][] item = (String[][]) ois.readObject();
                historyList.add(item);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                break;
            } catch (IOException e) {
                // 捕获EOFException表示已读取到文件末尾
                if (e instanceof java.io.EOFException) {
                    break;
                } else {
                    e.printStackTrace();
                    break;
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return historyList;
}

四、注意事项

  • String[][]本身是可序列化的(数组和String均实现了Serializable接口),无需额外处理;
  • 可以替换临时文件路径为系统临时目录(System.getProperty("java.io.tmpdir")),提升代码兼容性;
  • 异常处理可根据业务需求调整,比如抛出自定义异常而非仅打印堆栈。

内容的提问来源于stack exchange,提问作者VS Puzzler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:35:56