11

オブジェクトをシリアル化し、ファイルとして HDD に保存します。私がそれを読んでいるとき、いくつかの場合にのみEOFExceptionをスローします。数時間のデバッグの後、問題を見つけることができません。

これが私のコードです:

   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);
                }
            }

        }
    }

オブジェクトを取得する場合:

  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;
    }

スタックトレース:

java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273) で java.io.ObjectInputStream.readObject(ObjectInputStream.java: 348) java.util.LinkedList.readObject(LinkedList.java:776) で sun.reflect.GeneratedMethodAccessor583.invoke(不明なソース) で sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) で java.lang.reflect で.Method.invoke(Method.java:585) で java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) で java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) で java.io.ObjectInputStream.readOrdinaryObject( ObjectInputStream.java:1719) で java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) で java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908) で java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832) で java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) で java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) でio.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)

質問: シリアライズされたオブジェクトが壊れてしまいましたが、これはゴミですか?
このオブジェクトは、ユーザーが保存した UI のレンダリングを担当するためです。ユーザーがログインすると、以前に保存した UI の状態をレンダリングする必要があります。ただし、一部のユーザーでは、ファイルを逆シリアル化できません。

4

3 に答える 3

7

EOFExceptionファイルの終わりを越えて読み込もうとしていることを意味します。通常、読み取るオブジェクトが他にあるかどうかは、試してみる以外に知る方法がないため、EOFExceptionそもそも問題と見なすべきではありません。ファイルにさらにオブジェクトがあることがわかっていると思われる状況でスローされた場合、たとえば、ファイルにオブジェクト数をプレフィックスとして付けた場合、ファイルを書き込んだコードに問題があるか、ファイルが破損している可能性があることを示しています。自体。もう 1 つの例は、長さ 0 であってはならない長さ 0 のファイルです。どんな問題でも、読んで終わりでは解決できず、時既に遅​​し。

于 2012-06-01T22:40:47.220 に答える
3

ファイルの書き込みと読み取りに問題はありません。

だから私の最善の推測は、問題はファイルレベルにあるということです. 例えば:

  • あるファイルを書き込んで別のファイルを読み込んでいる可能性があります。
  • ファイルの書き込みが完了する前にファイルを読み取っている可能性があります。
  • 書き込みコードと読み取りコードの実行の間に、他の何かがファイルを壊している可能性があります。

File.length() を使用するトレース コードを追加して、ファイル サイズを書き込んだ後、読み取る前に確認することをお勧めします。


他のいくつかの可能性:

  • ライターとリーダーのコードがMyClass、互換性のない表現と同じ serialVersionId 値を持つ異なるバージョンの (または依存クラス) を使用している、または

  • 互換性のないカスタムメソッドreadObjectとメソッドを使用している可能性があります。writeObject

于 2012-06-01T12:34:05.337 に答える
1

私の場合、EOF 例外は、ファイルへの読み取りと書き込みがスレッドセーフであることを確認することで解決されました。Stephen Cが上で答えたように、別のスレッドから読み込もうとしているファイルに書き込もうとすると、この場合EOF例外をスローするObjectInputStreamを踏んでいる可能性があります。

于 2016-01-27T18:44:26.993 に答える