如何在不获取java.io.StreamCorruptedException的情况下追加到ObjectInputStream:无效类型代码:AC?

2022-09-03 13:37:03

我正在尝试从文件中读取一些对象。该代码在第一次迭代中工作正常,在第二次迭代中,它给出了一个 StreamCorruptedException。这是我的代码,

private ArrayList<Cheque> cheques = null;
ObjectInputStream ois = null;
        try {
            cheques = new ArrayList<Cheque>(4);
            ois = new ObjectInputStream(new FileInputStream("src\\easycheque\\data\\Templates.dat"));
            Object o = null;
            try {
                o = ois.readObject();
                int i=1;
                while (o != null) {
                    cheques.add((Cheque) o);
                    System.out.println(i++); // prints the number of the iteration
                    o = ois.readObject(); // exception occurs here
                }
            } catch (ClassNotFoundException ex) {// for ois readObject()
                Logger.getLogger(TemplateReader.class.getName()).log(Level.SEVERE, null, ex);

            } catch (EOFException ex) {// for ois readObject()
                // end of the file reached stop reading
                System.out.println("ois closed");
                ois.close();

            }
        } catch (IOException ex) {
            Logger.getLogger(TemplateReader.class.getName()).log(Level.SEVERE, null, ex);
        }

以下是例外的一部分。在打印之前,打印此“1”(由于sout)

SEVERE: null
java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 

我不明白为什么会发生这种情况。在一些论坛帖子中,我遇到过当您在编写文件时附加到文件时会发生这种情况。这是真正的原因吗?(我在写入阶段附加到文件)。如果是这样,是否有正确的方法来读取附加的文件?

这是我用来写入文件的代码

 ObjectOutputStream objectOut = new ObjectOutputStream(new FileOutputStream("src\\easycheque\\data\\templates.dat", true));

 objectOut.writeObject(cheque);
 objectOut.flush();
 objectOut.close();

写作不是一个迭代过程。

谢谢:)


答案 1

(我在写入阶段附加到文件)

这就是问题所在。不能追加到 ObjectOutputStream。这肯定会破坏流,你会得到StreamCorruptedException。

但是我已经在SO上留下了这个问题的解决方案:一个可附加的ObjectOutputStream。

编辑

从作者那里,我看到你写了一个支票对象,然后冲洗并关闭了流。从读者那里,我清楚地看到,你正在尝试阅读多个支票对象。你可以阅读第一个,但不能阅读其余的。所以对我来说,这是非常清楚的,你重新打开流并附加越来越多的支票对象。这是不允许的。

您必须在“一个会话”中写下所有支票对象。或者使用 AppendableObjectOutputStream 而不是标准的 ObjectOutputStream。


答案 2

在不关闭基础 FileInputStream 的情况下创建新的 ObjectInputStream 可以解决此问题:

    FileInputStream fin = new FileInputStream(file);
    while (...) {
        ObjectInputStream oin = new ObjectInputStream(fin);
        Object o = oin.readObject();
        ...
    }
    fin.close();