Alex Rivera | Logout

How can I append to an existing java.io.ObjectStream?

Asked 2010-01-19T15:37:56.153
10

As for now I will get java.io.StreamCorruptedException when I try to append an Object. I have searched the Internet for a way to overcome that. The answer I found so far is it can't be done. A way around this problem is to write the objects into a list and then write the list to the file.

But I have to overwrite that file everytime when I add new objects. It seems not to be the optimal solution in overtime.

Is there a way to append objects to an existing object stream?

Edit
Report

1 Answer

5

The best article I've found on this topic is: http://codify.flansite.com/2009/11/java-serialization-appending-objects-to-an-existing-file/

The "solution" that overrides ObjectOutputStream is simply wrong. I've just finished investigating a bug that was caused by that (wasting two precious days). Not only that it would sometimes corrupt the serialized file but even managed to read without throwing exceptions and in the end providing garbage data (mixing fields). For those in disbelief, I'm attaching some code that exposes the problem:

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) throws Exception {

        File storageFile = new File("test");
        storageFile.delete();

        write(storageFile, getO1());
        write(storageFile, getO2());
        write(storageFile, getO2());

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(storageFile));
        read(ois, getO1());
        read(ois, getO2());
        read(ois, getO2());
    }

    private static void write(File storageFile, Map<String, String> o) throws IOException {
        ObjectOutputStream oos = getOOS(storageFile);
        oos.writeObject(o);
        oos.close();
    }

    private static void read(ObjectInputStream ois, Map<String, String> expected) throws ClassNotFoundException, IOException {
        Object actual = ois.readObject();
        assertEquals(expected, actual);
    }

    private static void assertEquals(Object o1, Object o2) {
        if (!o1.equals(o2)) {
            throw new AssertionError("\n expected: " + o1 + "\n actual:   " + o2);
        }
    }

    private static Map<String, String> getO1() {
        Map<String, String> nvps = new HashMap<String, String>();
        nvps.put("timestamp", "1326
answered 2012-01-13T18:15:03.000

Your Answer