11

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.

Jama A.
  • 15,680
  • 10
  • 55
  • 88
  • 2
    The paragraph of code that closes the `FileOutputStream` is unneeded; closing the `ObjectOutputStream` also closes the file. – Ernest Friedman-Hill Jun 01 '12 at 11:33
  • @MonsterTruck, I have added stacktrace – Jama A. Jun 01 '12 at 11:37
  • By any chance, is `oiStream.readObject()` called very soon after `ooStream.writeObject()`? I am assuming that the HDD is still in the process of writing that file to the disk and readObject() attempts to read it. To confirm put a deliberate `Thread.Sleep(5000);` right before the `readObject()` call. – Apoorv Jun 01 '12 at 11:41
  • @Monster Truck, I don't think so, there is enough time between reading and writing it... – Jama A. Jun 01 '12 at 11:47
  • Try splitting the problem into write or read. Wrap the read in a function that catches EOFException and retries the read one more time. If it reliably fails on the retry, you know the problem is writing. – John Watts Jun 01 '12 at 11:47
  • @JohnWatts, I tried as you told by catching `EOFException` but it continues infinite recursively... – Jama A. Jun 01 '12 at 12:14
  • Good. So the problem is writing. Do you have a way to stop once you detect this? Then maybe you could compare the contents of the file against a known good one. – John Watts Jun 01 '12 at 15:30

3 Answers3

7

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
3

I cannot see any problem with the writing and reading of the file.

So my best guess is that the problem is at the file level. For example:

  • you could be writing one file and reading a different one, or
  • you could be reading the file before the file write completes, or
  • something else could be clobbering the file in between the running of your write code and read code.

I suggest that you add some tracing code that uses File.length() to find out what the file size is after you've written it and before you read it.


A couple of other possibilities:

  • the writer and reader code is using different versions of MyClass (or a dependent class) with incompatible representations and the same serialVersionId values, or

  • you could be using custom readObject and writeObject methods that are incompatible.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

In my case, EOF Exception was solved by ensuring the read and writes to the file were thread safe. Like Stephen C answered above, if you try to write to a file which you also are trying to read from say from another thread, you may be stepping on the ObjectInputStream which is going to throw EOF Exception in this case.

simplatek
  • 637
  • 7
  • 7