Java FileInputStream ObjectInputStream 到达文件末尾 EOF

发布于 2024-08-28 19:07:58 字数 363 浏览 11 评论 0原文

我试图使用 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++;
    }

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?

    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++;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

恬淡成诗 2024-09-04 19:07:58

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

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

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

A better approach would be to use some meta-data. That is, rather than asking the ObjectInput how 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.

兲鉂ぱ嘚淚 2024-09-04 19:07:58

我今天也遇到了同样的问题。尽管这个问题很老了,但问题仍然存在,并且没有提供干净的解决方案。应避免忽略 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++;
   }

I had the same problem today. Although the question is quite old, the problem remains and there was no clean solution provided. Ignoring EOFException should 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.

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

   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++;
   }
星星的軌跡 2024-09-04 19:07:58

不可以。捕获 EOFException 并使用它来终止循环。

No. Catch EOFException and use that to terminate the loop.

云巢 2024-09-04 19:07:58

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

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

当您序列化数据时。

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);

when you serialize the data.

缪败 2024-09-04 19:07:58

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

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

import java.io.Serializable;

public enum ObjectStreamStatus implements Serializable {
    EOF
}

然后在读取对象的代码中,我在对象读取中检查了此 EOF 对象环形。

It's curious that the API doesn't supply a more elegant solution to this. I guess the EOFException would 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:

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.

肥爪爪 2024-09-04 19:07:58

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

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

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.

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

相权↑美人 2024-09-04 19:07:58

看起来问题出在您写出的数据上。假设数据按照这段代码的预期写入,应该不会有问题。

(我看到您正在读取 String。此 ObectInputStream 不适用于读取文本文件。使用 InputStreamReaderBufferedReader.readLine<同样,如果您使用 DataOutputSteam.writeUTF 写入文件,请使用 DataInputStream.readUTF 读取它。

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 ObectInputStream isn't for reading text files. Use InputStreamReader and BufferedReader.readLine for that. Similarly if you have written the file with DataOutputSteam.writeUTF, read it with DataInputStream.readUTF)

旧故 2024-09-04 19:07:58

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

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.

淡莣 2024-09-04 19:07:58

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文