5

ObjectOutputStream を使用して、シリアル化されたオブジェクトのファイルを作成しています。次に、ObjectInputStream を readObject() メソッドで使用して、ファイルからオブジェクトを取得します。

初めてでもうまくいきます。つまり、ファイルが存在せず、それを開いて任意の数のオブジェクトを追加すると、ObjectInputStream オブジェクトを開いてすべてのオブジェクトにアクセスできます。

ただし、後で同じファイルを (append オプションを使用して) 開き、さらにオブジェクトを追加すると、ObjectInputStream オブジェクトは java.io.StreamCorruptedException: "invalid type code: AC" エラーを受け取り、新しいオブジェクトを開始する必要があります。

他の誰かがこれに遭遇しましたか?Deitel の本からいくつかの基本的な教科書の例に戻っても、同じエラーが発生します。

編集:これを見つけました-シリアル化されたストリームを閉じて追加モードで再度開いた後は、その末尾に追加することはできません。書き込みは機能しているように見えますが、後でファイルを読み取ろうとすると、java.io.StreamCorruptedException が発生します。「http://mindprod.com/jgloss/gotchas.html#SERIALIZATION」で

4

3 に答える 3

4

各オブジェクトは、個々のオブジェクトとしてではなく、オブジェクト ストリームの一部としてシリアル化されます。「Object Stream Serialization Protocol」は、ほとんどのファイル形式 (ただし ZIP ではありません!) と同様にヘッダーを持っています。これは、すべての newObjectInputStreamがファイルの先頭でのみ見つけることを期待するものです。ストリームの途中に配置しても機能しません。また、ストリームには後方参照があるため、(特に指定がない限り) オブジェクトが 2 回書き出されることはありません。

ObjectInputStreamしたがって、すべてに一致するように新しいを作成する必要がありますObjectOutputStream。いくつかの内部バッファリングがあります。それが問題を引き起こす場合は、ストリームをスライスする前にスライスする必要がありますObject(In|Out)putStream

于 2009-06-10T20:17:43.887 に答える
1

ストリームのプロデューサーとコンシューマーが独立している場合は、毎回出力ファイルを上書きしてタイムスタンプファイルを追加するだけで、コンシューマーがリロードする時間を知ることができます。

例えば、

SomeObject[] obj = new SomeObject[numObjects];
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file");
out.writeObject(obj);
out.close();
long ts = System.currentTimeMillis();
ObjectOutputStream tout =
        new ObjectOutputStream(new FileOutputStream("timestamp.obj");
tout.writeObject(new Long(ts));

その後、コンシューマーは、timestamp.objファイルを数分ごとにポーリングし、変更されている場合はSomeObject[]、ストリームから再度開くことができます。

ObjectInputStream in =
        new ObjectInputStream(new FileInputStream("timestamp.obj"));
Long ts = (Long)in.readObject();

if (ts > prevts) {
    ObjectInputStream in2 = new ObjectInputStream(new FileInputStream("file"));
    SomeObject[] obj = (SomeObject[])in.readObject(); 
    prevts = ts;
}
于 2009-06-10T23:19:04.880 に答える
1

ObjectStream には、ヘッダーとフッターが含まれています。また、ステートフルな情報も含まれます。つまり、書き込む内容は、既に書き込んだオブジェクトに基づいています。

したがって、既存の ObjectStream に追加することはできません。できることは、ファイルを書き直して毎回オブジェクトを追加するか、独自のプロトコルでストリームをラップして、複数のストリームを正しく読み書きできるようにすることです。

ObjectStream は、同じコード ベースでデータの読み取り/書き込みを行う場合に最適に機能します (特に読み取り/書き込みクラスの場合)。ObjectStream は、コードのバージョン間または異なるアプリケーション間で移植できるようには設計されていません。

于 2009-06-11T20:31:18.410 に答える