Java FileInputStream ObjectInputStream到达文件结尾EOF

时间:2010-04-12 23:50:32

标签: 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++;
    }

9 个答案:

答案 0 :(得分:25)

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

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

答案 1 :(得分: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++;
   }

答案 2 :(得分:6)

没有。捕获EOFException并使用它来终止循环。

答案 3 :(得分:2)

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

添加: out.writeObject(NULL);

序列化数据时。

答案 4 :(得分:1)

奇怪的是API没有为此提供更优雅的解决方案。我想EOFException会起作用但我总是被鼓励将异常视为意外事件,而在这里你经常会期望对象流结束。

我尝试通过编写一种“标记”对象来表示对象流的结束:

import java.io.Serializable;

public enum ObjectStreamStatus implements Serializable {
    EOF
}


然后在代码中读取对象,我在对象读取循环中检查了这个EOF对象。

答案 5 :(得分:0)

不,您需要知道二进制文件中有多少个对象。您可以在文件开头写入对象的数量(例如使用writeInt)并在加载时读取它。

另一种选择是调用ois.available()并循环直到它返回0.但是,我不确定这是否100%确定。

答案 6 :(得分:0)

看起来问题在于你写的数据。假设数据是按照此代码的预期编写的,那么应该没有问题。

(我看到您正在阅读String s。此ObectInputStream不是用于阅读文本文件。请使用InputStreamReaderBufferedReader.readLine。如果您已经写过包含DataOutputSteam.writeUTF的文件,请使用DataInputStream.readUTF

进行阅读

答案 7 :(得分:0)

ObjectInputStream的可用方法不能用于终止循环,因为即使在文件中有要读取的对象,它也会返回0。将null写入文件似乎不是一个好的解决方案,因为对象可以为null,然后将其解释为文件的结尾。我认为捕获EOFException以终止循环是一种更好的做法,因为如果发生EOFException(因为你到达了文件的末尾或其他原因),你必须终止循环。

答案 8 :(得分:-1)

结束循环的最佳方法可以通过在末尾添加一个空对象来完成。读取null对象时可以用作边界条件来退出循环。捕获EOFException也解决了目的,但需要很少m