Java ObjectInputStream.readObject导致EOFEException

Java ObjectInputStream.readObject导致EOFEException,java,io,Java,Io,我正在编写一个简单的客户机-服务器应用程序,服务器在其中打开一个线程,该线程监视一个目录中的文件创建。这些文件是序列化对象。线程应该对它们进行反序列化,读取数据并创建一个新对象将其发送到客户端。 一般来说,它工作得很好,但有时我会: 位于的java.io.EOFException ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571) 位于java.io.ObjectInputStream.read

我正在编写一个简单的客户机-服务器应用程序,服务器在其中打开一个线程,该线程监视一个目录中的文件创建。这些文件是序列化对象。线程应该对它们进行反序列化,读取数据并创建一个新对象将其发送到客户端。 一般来说,它工作得很好,但有时我会:

位于的java.io.EOFException ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571) 位于java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1315) 位于java.io.ObjectInputStream.readObject(ObjectInputStream.java:369) 在ServerSend.start(ServerSend.java:58) 运行(ServerSend.java:25) 运行(Thread.java:722)

但为什么会这样?为什么只是有时候。。。 我读取对象的程序的一部分:

FileInputStream fileStream = new FileInputStream(dirpath+"/"+t);
ObjectInputStream ois = new ObjectInputStream(fileStream);
Object toSend = ois.readObject();

其他一些程序创建这些对象,我的StreamReader希望读取:

FileOutputStream fileStream = new FileOutputStream(filepath_to_where_listening);
            ObjectOutputStream oos = new ObjectOutputStream(fileStream);
            oos.writeObject(mmout);

该文件是以原子方式创建的吗?或者,您是否可能在创建文件时正在读取该文件

您可以创建扩展名为
.tmp
的文件,然后在文件完成后删除扩展名。这取决于所使用的文件系统,但我希望这对于大多数(所有?)Unix/Linux文件系统来说是原子的

或者,您的写入过程可以写入该文件,然后写入相应的标志文件,该文件指示已完成对序列化对象的写入(例如,
objectfile.ser
objectfile.ser.done


另一种解决方案(非常不确定)是监视文件,然后在读取之前等待指定的时间,以允许它完成创建。

这可能是由两个条件引起的

  • 文件未正确关闭,导致文件结尾被截断。如果文件被丢弃,GC可以为您关闭该文件,但这种行为是不可靠的
  • ObjectOutputStream writexxx,而ObjectOutputStream readYyyy,其中Xxxx不是Yyyy。e、 g.writeObject和readInt将导致此错误

我同意,他很有可能在文件“定稿”之前访问该文件。是的,还有另一个程序,创建并序列化对象。FileOutputStream已完成。我可以做些什么来防止这些错误?有些程序自动写入对象——一旦收到EOFEException,就无法继续读取数据。您可以捕获异常并继续读取数据。简单的解决方案是,当您完成数据流时,始终正确地关闭数据流,这样您就不会遇到此问题。此外,在文件完成写入之前,不要读取文件。文件不是邮件的好替代品。感谢您的解释。这是非常有帮助的问题是线程是自动创建的,并且数量很大。它们必须相互通信,因此每个线程都有自己的正在侦听的目录:等待文件完成的一个简单方法是要么。a) 检查修改日期和/或b)如果文件未能读取,则在延迟后重新读取文件。