25

readObjectを使用してバイナリファイルの行数を読み取ろうとしていますが、IOExceptionEOFが発生します。私はこれを正しい方法でやっていますか?

    FileInputStream istream = new FileInputStream(fileName);
    ObjectInputStream ois = new ObjectInputStream(istream);

    /** calculate number of items **/
    int line_count = 0;
    while( (String)ois.readObject() != null){            
        line_count++;
    }
4

9 に答える 9

31

readObject()nullEOFに戻りません。をキャッチしEOFExceptionてEOFとして解釈することはできますが、これでは、通常のEOFと切り捨てられたファイルを区別することはできません。

より良いアプローチは、いくつかのメタデータを使用することです。つまり、ストリームに含まれるオブジェクトの数を尋ねるのではなくObjectInput、カウントをどこかに保存する必要があります。たとえば、カウントやその他のメタデータを記録するメタデータクラスを作成し、インスタンスを各ファイルの最初のオブジェクトとして保存できます。または、特別なEOFマーカークラスを作成し、インスタンスを各ファイルの最後のオブジェクトとして保存することもできます。

于 2010-04-12T23:59:13.510 に答える
18

今日も同じ問題がありました。質問はかなり古いものですが、問題は残っており、クリーンな解決策は提供されていませんでした。EOFException一部のオブジェクトが正しく保存されなかった場合にスローされる可能性があるため、無視することは避けてください。nullを書き込むと、他の目的でnull値を使用できなくなります。最後available()に、オブジェクトの数が不明なため、オブジェクトストリームで使用すると常にゼロが返されます。

私の解決策は非常に簡単です。ObjectInputStreamFileInputStreamなどの他のストリームの単なるラッパーです。ObjectInputStream.available ()ゼロを返しますが、FileInputStream.availableはいくつかの値を返します。

   FileInputStream istream = new FileInputStream(fileName);
   ObjectInputStream ois = new ObjectInputStream(istream);

   /** calculate number of items **/
   int line_count = 0;
   while( istream.available() > 0) // check if the file stream is at the end
   {
      (String)ois.readObject();    // read from the object stream,
                                   //    which wraps the file stream
      line_count++;
   }
于 2012-11-13T14:29:12.107 に答える
6

いいえ。それをキャッチEOFExceptionして使用し、ループを終了します。

于 2010-04-13T07:37:11.823 に答える
4

ファイルの最後にnullオブジェクトを書き込んだ場合、それを読み戻すとnull値が取得され、ループが終了する可能性があります。

追加するだけです:out.writeObject(null);

データをシリアル化するとき。

于 2018-04-11T15:24:46.523 に答える
1

APIがこれに対してより洗練されたソリューションを提供していないのは不思議です。うまくいくと思いEOFExceptionますが、例外を予期しないイベントと見なすように常に勧められてきましたが、ここでは、オブジェクトストリームが終了することを期待することがよくあります。

オブジェクトストリームの終わりを示す一種の「マーカー」オブジェクトを作成することで、これを回避しようとしました。

import java.io.Serializable;

public enum ObjectStreamStatus implements Serializable {
    EOF
}


次に、オブジェクトを読み取るコードで、オブジェクト読み取りループでこのEOFオブジェクトをチェックしました。

于 2013-12-07T18:09:51.850 に答える
0

ObjectInputStreamの使用可能なメソッドは、ファイルに読み取るオブジェクトがある場合でも0を返すため、ループを終了するために使用できません。オブジェクトがnullになる可能性があり、それがファイルの終わりとして解釈される可能性があるため、ファイルにnullを書き込むことも良い解決策ではないようです。EOFExceptionが発生した場合(ファイルの終わりに到達したか、その他の理由で)、とにかくループを終了する必要があるため、EOFExceptionをキャッチしてループを終了することをお勧めします。

于 2012-08-14T13:34:26.030 に答える
0

いいえ、バイナリファイルにオブジェクトがいくつあるかを知る必要があります。ファイルの先頭にオブジェクトの数を書き込み(たとえば、writeIntを使用)、ロード中に読み取ることができます。

もう1つのオプションは、ois.available()を呼び出して、0が返されるまでループすることです。ただし、これが100%確実かどうかはわかりません。

于 2010-04-13T00:02:56.933 に答える
0

書き出したデータに問題があるようです。このコードで期待どおりにデータが書き込まれていれば、問題はありません。

Stringsを読んでいるようです。これObectInputStreamはテキストファイルを読むためのものではありません。それを使用InputStreamReaderBufferedReader.readLineてください。同様に、でファイルを書き込んだ場合はDataOutputSteam.writeUTF、で読んでくださいDataInputStream.readUTF

于 2010-04-13T00:32:22.113 に答える
-1

ループを終了するための最良の方法は、最後にnullオブジェクトを追加することです。nullオブジェクトの読み取り中は、ループを終了するための境界条件として使用できます。EOFExceptionをキャッチすることも目的を解決しますが、数mかかります

于 2011-11-03T07:27:42.490 に答える