【问题标题】:java.io.EOFException when try to read from a socket尝试从套接字读取时出现 java.io.EOFException
【发布时间】:2013-07-10 07:15:57
【问题描述】:

我不知道为什么会出现 java.io.EOFException。从服务器获取二进制流后,我想写一个文件。

这是我的代码

inputStream = new DataInputStream(new BufferedInputStream(connection.getInputStream()));
FileOutputStream fos = new FileOutputStream("D:/Apendo API resumable download.txt");

byte b = inputStream.readByte();
while(b != -1){
        fos.write(b);
        b = inputStream.readByte();                       
       }
fos.close();

堆栈跟踪

java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:267)
at HttpRequestJSON.JSONRequest.sendRequest(JSONRequest.java:64)
at HttpRequestJSON.Main.main(Main.java:56)

【问题讨论】:

  • 您在哪一行得到了异常?
  • 当 b = inputStream.readByte();在 while(b != -1)
  • Err,实际上是在尝试读取文件时。

标签: java file io eofexception


【解决方案1】:

DataInputStream.readByte API 没有说它在 EOS 上返回 -1,它说

返回:此输入流的下一个字节为带符号的 8 位字节。

抛出:EOFException - 如果此输入流已结束。

假设在使用 DataInputStream.readByte 时,我们知道流中还剩下多少字节。否则我们可以使用EOFException作为EOS的一个指标。

顺便说一句,如果你使用 read() 你会在没有 EOFException 的情况下在 EOS 上得到 -1

【讨论】:

  • 如果出现EOFException,是否意味着DataInputStream已经写完字节了?
  • 是的,这意味着没有更多字节,流 EOS 结束。顺便说一句,如果你使用 read() 你会得到 -1 而没有 EOFException
  • 这意味着它已经完成了阅读,看在上帝的份上。输入流不写任何东西。
【解决方案2】:

来自DataInputStream Javadoc

数据输入流允许应用程序以与机器无关的方式从底层输入流中读取原始 Java 数据类型。

我不确定您是否需要,但您可以自己决定。一般来说,如果您只是下载数据并写入文件,则不需要它 - 只需使用 BufferedInputStream

readByte() 方法读取一个字节(因此得名),当流在读取所有字节之前到达末尾时,它会抛出一个EOFException。听起来可能有点混乱,但异常是在读取输入时引发的,而不是写入文件。事实上,这是判断DataInputStream是否结束的唯一方法。

但是,请再次考虑使用 BufferedInputStream,因为它可能就是您所需要的。

【讨论】:

    【解决方案3】:

    你已经读过这个字节了,那你为什么还要在这段时间里读呢?再加上你在 while 的检查不正确,你不会得到 DIS.readByte 的 -1。尝试使用 read()。

    【讨论】:

      【解决方案4】:

      这取决于您何时使用客户端 - 服务器实现,客户端“始终处于运行状态”,而套接字始终保持运行。

      如果套接字连接已启动并且您使用例如 ObjectInputStream,则当客户端关闭套接字 (socket.close) 时将出现“EOFException”,或者当未检查 socket.close() 时将出现“java.net.SocketException: Connection”重置终于确定了……

      但是,如果您保持客户端和套接字连接,ObjectInputStream.readObject() 将保留并在这种情况下侦听您想要的内容。是的,当您仅调用 read() 时,您将得到-1,如果客户端被杀死并且您正在为一个客户端处理服务器上的一个线程,您将只会得到-1,并且线程将永远存在(如果您不手动杀死它或杀死它整个服务器)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        • 2014-11-09
        • 2018-01-18
        相关资源
        最近更新 更多