Вопрос по exception, eof, java – Как предотвратить InputStream.readObject () от выброса EOFException?

11

Я сериализую объект и сохраняю его в виде файла на моем жестком диске. Когда я читаю это, только в некоторых случаяхEOFException, После пары часов отладки я не могу найти проблему.

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: Мой сериализованный объект теперь поврежден, а теперь это мусор?
Потому что этот объект отвечает за рендеринг пользовательского интерфейса, сохраненного пользователем. Если пользователь входит в систему, он должен отображать ранее сохраненное состояние пользовательского интерфейса. Однако для некоторых пользователей файл не может быть десериализован.

@ Monster Truck, я так не думаю, между прочтением и написанием текста достаточно времени ... Õzbek
Stacktrace, пожалуйста? Apoorv Khurasia
@MonsterTruck, я добавил стек Õzbek
По случайностиoiStream.readObject() позвонили очень скоро послеooStream.writeObject()? Я предполагаю, что жесткий диск все еще находится в процессе записи этого файла на диск, и readObject () пытается прочитать его. Подтвердить поставить умышленноThread.Sleep(5000); прямо передreadObject() вызов. Apoorv Khurasia
Абзац кода, который закрываетFileOutputStream не требуется; закрытиеObjectOutputStream также закрывает файл. Ernest Friedman-Hill

Ваш Ответ

3   ответа
1

В моем случае исключение EOF было решено путем обеспечения того, что чтение и запись в файл были поточно-ориентированными. Как Стивен C ответил выше, если вы пытаетесь записать в файл, который вы также пытаетесь прочитать, скажем, из другого потока, вы можете наступить на ObjectInputStream, который в этом случае вызовет исключение EOF.

6

EOFException означает, что вы пытаетесь прочитать за конец файла. Обычно у вас нет никакого способа узнать, есть ли другие объекты для чтения, кроме как попробовать, так что вам не следуетEOFException как проблема в первую очередь. Если он брошен в ситуации, когда вы думаете, что выknow в файле есть больше объектов, например если вы добавили к файлу счетчик объектов, это указывает на проблему с кодом, написавшим файл, или на возможное повреждение самого файла. Другой пример - это файл нулевой длины, который не должен быть нулевой длины. Какова бы ни была проблема, она не может быть решена к концу чтения, уже слишком поздно.

2

Я не вижу никаких проблем с записью и чтением файла.

Поэтому я думаю, что проблема на уровне файлов. Например:

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.

Я предлагаю вам добавить некоторый код трассировки, который использует File.length (), чтобы узнать, какой размер файла есть после того, как вы его написали и до того, как прочитали.

Пара других возможностей:

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.

Похожие вопросы