Java FileInputStream ObjectInputStream到达文件结尾EOF

use*_*514 21 java file-io fileinputstream objectinputstream

我试图使用readObject读取二进制文件中的行数,但我得到IOException EOF.我这样做是对的吗?

    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++;
    }
Run Code Online (Sandbox Code Playgroud)

eri*_*son 27

readObject()null在EOF 没有返回.您可以捕获EOFException并将其解释为EOF,但这将无法检测到将正常EOF与已截断的文件区分开来.

更好的方法是使用一些元数据.也就是说ObjectInput,您应该将计数存储在某处,而不是询问流中有多少对象.例如,您可以创建一个元数据类来记录计数和其他元数据,并将实例存储为每个文件中的第一个对象.或者,您可以创建一个特殊的EOF标记类,并将实例存储为每个文件中的最后一个对象.

  • 如果写入流的最后一个'对象'是'null`,那么你将读取`null`引用.`null`s是串行形式的一部分是正常的,并且在串行格式中有一个特殊的表示形式.最后的"null"或其他一些哨兵,比计数更清晰. (6认同)

Tom*_*asz 19

我今天遇到了同样的问题.虽然这个问题很老,但问题仍然存在,并且没有提供干净的解决方案.EOFException应该避免忽略,因为当某个对象未正确保存时可能会抛出.写入null显然会阻止您将null值用于任何其他目的.最后available()在对象流上使用总是返回零,因为对象的数量是未知的.

我的解决方案非常简单.ObjectInputStream它只是一些其他流的包装器,例如FileInputStream.虽然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++;
   }
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于 ObjectInputStream 不做任何缓冲的情况。是这种情况吗?javadoc 对此没有任何说明。 (4认同)

use*_*421 6

不.捕获EOFException并使用它来终止循环.

  • 汤姆1.请停止胡言乱语并回答问题.准确地告诉我们这是什么'危险':catch(EOFException exc){break; 2.请告诉我们如何在不捕获EOFException的情况下读取整个ObjectInputStream,并且不限制该流的编写器如何执行它.你不能.它无法完成.EOFException是唯一的机制. (5认同)

小智 6

如果您在文件末尾写入一个空对象,当您读回它时,您将得到一个空值并可以终止循环。

只需添加:out.writeObject(null);

当您序列化数据时。