How to prevent InputStream.readObject() from throwing EOFException?

Õzbek picture Õzbek · Jun 1, 2012 · Viewed 22.6k times · Source

I serialize an object and save it as a file on my HDD. When I'm reading it, in only some occasions it throws EOFException. After couple of hours debugging I am not able to find a problem.

Here is my code:

   public void serialize(MyClass myClass,String path) {
        FileOutputStream foStream = null;
        ObjectOutputStream ooStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            foStream = new FileOutputStream(file);
            ooStream = new ObjectOutputStream(foStream);
            ooStream.writeObject(myClass);
        } catch (Throwable t) {
            log.error(t);
        } finally {
            if (ooStream != null) {
                try {
                    ooStream.flush();
                    ooStream.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }

        }
    }

For getting Object:

  public MyClass deSerialize(String path) {
        MyClass myClass=null;
        FileInputStream fiStream = null;
        ObjectInputStream oiStream = null;
        String errorMessage = "";
        try {
            File file = new File(path);
            if (!file.exists()) {
                return null;
            }
            fiStream = new FileInputStream(path);
            oiStream = new ObjectInputStream(fiStream);
            Object o = oiStream.readObject();
            myClass = (MyClass) o;
        } catch (Throwable t) {
            log.warn(t);
        } finally {
            if (oiStream != null) {
                try {
                    oiStream.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
        return myClass;
    }

Stacktrace:

java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2498) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348) at java.util.LinkedList.readObject(LinkedList.java:776) at sun.reflect.GeneratedMethodAccessor583.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)

Question: My serialized object is now corrupted and then is it rubbish now?
Because this object is responsible for rendering the UI which saved by user. If User logs in it should render previously saved state of UI. However for some user the file cannot be deserialized.

Answer

user207421 picture user207421 · Jun 2, 2012

EOFException means you are trying to read past the end of the file. Normally you don't have any way of knowing whethere there are more objects to read, other than trying it, so you shouldn't regard EOFException as a problem in the first place. If it is thrown in a situation where you think you know there are more objects in the file, e.g. when you have prefixed an object count to the file, it indicates a problem with the code that wrote the file, or possible corruption of the file itself. Another example is a zero length file that shouldn't be zero length. Whatever the problem is, it can't be solved by the reading end, it is already too late.