2

私のファイルへの書き込み手順は次のとおりです(私が非クラスター化と呼んでいるモードで)

  1. ファイルの現在の位置にオブジェクトを書き込みます。別のファイル(インデックスファイルと呼ばれる)への書き込みの位置に注意して、オブジェクトをどこに配置したかがわかります。
  2. ゼロバイトを書き込んで、いくらかのスペース(ランダムに1/2/3/4 KBのスペース)を残します
  3. 手順1と2を繰り返します

ここで、ファイルからオブジェクトを読み戻すことにしました。しかし、私は使用したかったBufferedInputStream。ただしBufferedInputStream、ObjectInputStream内をカプセル化すると、一部のオブジェクトを読み取った後にエラーが発生します。これは、1つのバッファ読み取りの後に発生すると推測しています(つまり、バッファに収まる限り多くのオブジェクトが1回読み取られ、次にエラーが発生したとき)。

一方FileInputStream、作品の中に直接カプセル化するObjectInputStreamことは問題ありません。

必要に応じて、ファイル書き込みコードも提供します。以下のコードについては、お気軽にお問い合わせください。

public class RecordsFileReader {
    RecordsFile rFile;
    Iterator itr;
    FileInputStream fis;
    ObjectInputStream ois;

// The constructor
public RecordsFileReader(RecordsFile rFile) throws IOException, ClassNotFoundException {
    this.rFile = rFile;
    fis = new FileInputStream(rFile.getFileName());


    ObjectInputStream ois2 = new ObjectInputStream(new FileInputStream(rFile.getFileName() + ".index"));



    rFile.recordsLocationList =  (ArrayList <Long>) ois2.readObject();
    itr = rFile.recordsLocationList.iterator();
   /**********************************************************/
   /*          HERE IS THE PROBLEM.                          */
   /* Doesnt work when I additionally use BufferedInputStream*/
   /**********************************************************/

    ois = new ObjectInputStream(fis);

   /**********************************************************/     
}

public Tuple readNext() throws IOException, ClassNotFoundException {
    if(!itr.hasNext())
        return null;
    Long nextRecordPosition = itr.next();
    fis.getChannel().position(nextRecordPosition);
    //System.out.println((Tuple) ois.readObject());
    return ((Tuple) ois.readObject());
}

public void close() throws IOException {
    ois.close();
    fis.close();



}

public boolean hasNext() {
    return itr.hasNext();

}

}

public class RecordsFile {

boolean clustered;
private String fileName;

public RecordsFile(String fileName, boolean clustered) throws IOException {
    this.fileName = fileName;
    this.clustered = clustered;
}

/*
The byte positions at which the records are located in the file.
*/
ArrayList<Long> recordsLocationList= new ArrayList<Long>();

public String getFileName() {
    return fileName;
}

}

これはエラーの原因となっている変更です: ois = new ObjectInputStream(new BufferedInputStream(fis, 4096));代わりにois = new ObjectInputStream(fis);

エラーはjava.io.StreamCorruptionException: invalid type code : 00

編集 :

私は今問題を理解しました。私のfisが新しい位置に配置されている間、私のbisはその新しい位置にスキップされていませんでした。代わりに、bisは古い位置からのみ読み取ろうとしていたため、例外が発生しました。

4

1 に答える 1

2

これは、ストリーム(およびファイル)から読み戻されたバイトが(OISによって)オブジェクトとして解釈されているが、実際にはこれらのバイトは別のもの(実際のオブジェクトのバイト表現ではない)である場合を示しています。これは、バッファサイズが明示的に指定されていることが原因である可能性があります(手動で位置を設定しているという事実と組み合わされています)。

バッファサイズを明示的に指定せずに試すことをお勧めします。

ois = new ObjectInputStream(new BufferedInputStream(fis))

于 2011-09-14T21:33:23.487 に答える