Java FileInputStream ObjectInputStream 到达文件 EOF 的末尾

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2626163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:02:44  来源:igfitidea点击:

Java FileInputStream ObjectInputStream reaches end of file EOF

javafile-iofileinputstreamobjectinputstream

提问by user69514

I am trying to read the number of line in a binary file using readObject, but I get IOException EOF. Am I doing this the right way?

我正在尝试使用 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++;
    }

采纳答案by erickson

readObject()doesn't return nullat EOF. You could catch the EOFExceptionand interpret it as EOF, but this would fail to detect distinguish a normal EOF from a file that has been truncated.

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

A better approach would be to use some meta-data. That is, rather than asking the ObjectInputhow many objects are in the stream, you should store the count somewhere. For example, you could create a meta-data class that records the count and other meta-data and store an instance as the first object in each file. Or you could create a special EOF marker class and store an instance as the last object in each file.

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

回答by Manuel Darveau

No, you need to know how many objects there is in the binary file. You could write the number of objects at the beginning of the file (using writeInt for example) and read it while loading it.

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

Another option is to call ois.available() and loop until it returns 0. However, I am not sure if this is 100% sure.

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

回答by Tom Hawtin - tackline

It looks like the problem is with the data that you wrote out. Assuming the data is written as expected by this code, there shouldn't be a problem.

看起来问题出在您写出的数据上。假设数据按此代码的预期写入,应该没有问题。

(I see you are reading Strings. This ObectInputStreamisn't for reading text files. Use InputStreamReaderand BufferedReader.readLinefor that. Similarly if you have written the file with DataOutputSteam.writeUTF, read it with DataInputStream.readUTF)

(我看到您正在阅读Strings。这ObectInputStream不是用于阅读文本文件。使用InputStreamReaderandBufferedReader.readLine为此。同样,如果您使用 编写文件DataOutputSteam.writeUTF,请使用 阅读DataInputStream.readUTF

回答by user207421

No. Catch EOFExceptionand use that to terminate the loop.

不。捕捉EOFException并使用它来终止循环。

回答by Aditya

The best possible way to end the loop could be done by adding a null object at the end. While reading the null object can be used as a boundary condition to exit the loop. Catching the EOFException also solves the purpose but it takes few m

结束循环的最好方法是在最后添加一个空对象。同时读取空对象可以作为退出循环的边界条件。捕获 EOFException 也解决了目的,但需要几米

回答by Eunwoo Song

The available method of ObjectInputStream cannot used to terminate the loop as it returns 0 even if there are objects to be read in a file. Writing a null to a file doen't seem to be a good solution either since objects can be null which then would be interpreted as the end of file. I think catching the EOFException to terminate the loops is a better practice since if EOFException occurs(either because you reached the end of the file or some other reason), you have to terminate the loop anyway.

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

回答by Tomasz

I had the same problem today. Although the question is quite old, the problem remains and there was no clean solution provided. Ignoring EOFExceptionshould be avoided as it may be thrown when some object was not saved correctly. Writing null obviously prevents you from using null values for any other purposes. Finally using available()on the objects stream always returns zero, as the number of objects is unknown.

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

My solution is quite simple. ObjectInputStreamis just a wrapper for some other stream, such as FileInputStream. Although ObjectInputStream.available ()returns zero, the FileInputStream.available will return some value.

我的解决方案很简单。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++;
   }

回答by Kevin Leahy

It's curious that the API doesn't supply a more elegant solution to this. I guess the EOFExceptionwould work but I've always been encouraged to see exceptions as unexpected events whereas here you would often expect the object stream to come to an end.

I tried to work around this by writing a kind of "marker" object to signify the end of the object stream:

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

我试图通过编写一种“标记”对象来表示对象流的结束来解决这个问题:

import java.io.Serializable;

public enum ObjectStreamStatus implements Serializable {
    EOF
}


Then in the code reading the object i checked for this EOF object in the object reading loop.


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

回答by C. Paul Bond

If you write a null object at the end of the file, when you read it back you will get a null value and can terminate your loop.

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

Just add: out.writeObject(null);

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

when you serialize the data.

当您序列化数据时。