【问题标题】:Reading a web page in Java IOException Premature EOF在 Java IOException Premature EOF 中读取网页
【发布时间】:2012-11-03 14:32:48
【问题描述】:

我在阅读网页时经常收到“过早的 EOF”异常。

以下是 StackTrace

java.io.IOException: Premature EOF
    at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:556)
    at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:600)
    at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:687)
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:2968)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at Utilities.getPage(Utilities.java:24)  while ((line = rd.readLine()) != null) {
    at TalkPage.<init>(TalkPage.java:15)
    at Updater.run(Updater.java:65)

下面是getPage()方法

public static String getPage(String urlString) throws Exception {
    URL url = new URL(urlString);
    URLConnection conn = url.openConnection();
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer sb = new StringBuffer();
    String line;
    while ((line = rd.readLine()) != null) {  // LINE 24
        sb.append(line);
    }
    return sb.toString();
}

什么是永久 EOFException,为什么会在这种特殊情况下发生,如何避免?

其他一些信息:正在读取的页面大小约为 20 KB,我正在我的程序中读取许多这样的页面(大约 20 000)

【问题讨论】:

    标签: java io eof urlconnection


    【解决方案1】:

    这可能是因为您正在逐行读取内容,并且对于最后一行,文件可能缺少返回,以表示行结束。用这个替换你的while:

    int BUFFER_SIZE=1024;
    char[] buffer = new char[BUFFER_SIZE]; // or some other size, 
    int charsRead = 0;
    while ( (charsRead  = rd.read(buffer, 0, BUFFER_SIZE)) != -1) {
      sb.append(buffer, 0, charsRead);
    }
    

    【讨论】:

    • 最后一行文件可能缺少 return ::: 当我第二次阅读同一个网页时,我没有收到任何错误。所以,我认为这可能不是问题。而且,您能否回答问题的另一部分:什么是永久 EOFException
    • “permature EOFException”发生在您期待某些东西时,例如这里的行终止,但流中没有。
    • @Ranjith-SR2GF 你试过我的修复方法了吗?它应该每次都有效。您的问题可能是服务器没有推送最后一个结束行字符。
    • 目前,我已经完成了所需网页的下载。下次我需要做类似的工作时,我会尝试一下。感谢您的回答。
    • 为什么这不会导致 Premature EOF ,Premature EOF 在没有返回流结束的信号并且字节/字符仍然停止出现时出现,调用 rd.read() 将如何帮助,可能解决方案是正确的,但如果你能给出解释,将会很有帮助。
    【解决方案2】:

    这可能是因为服务器正在关闭连接。当我有一段代码打开连接时,我遇到了完全相同的问题,进行了一些其他处理,并且只有 然后 尝试下载输入流的内容 - 当它到流在其他处理上花费了几秒钟后,服务器显然关闭了连接,导致 IOException: Premature EOF.解决方案是要小心始终立即处理流的内容 - 否则,您将打开 HTTP 连接并处于空闲状态,最终线路另一端的服务器将挂断您。

    【讨论】:

    • 这也可能是因为服务器只发送标头而没有响应正文。
    【解决方案3】:

    【讨论】:

    【解决方案4】:

    您也可以尝试将缓冲区大小设置为 1。这有点帮助,如果您围绕它实现一个 try 逻辑,那么它应该可以解决问题。

    【讨论】:

      【解决方案5】:
              StringBuilder sb = new StringBuilder();
      
              try{                
                  URL url = new URL(address);
      
                  InputStream is = url.openStream();
      
                  InputStreamReader isr = new InputStreamReader(is);
      
                  BufferedReader in = new BufferedReader(isr);
      
                  String str;
      
                  while((str = in.readLine()) != null){
      
                      sb.append(str);
      
                      sb.append("\n");
                  }
      
                  in.close();
                  isr.close();
                  is.close();
      
                  return sb.toString();
      
               }catch(Exception e){
      
                   //OMG....
               }    
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 1970-01-01
        • 2021-03-04
        • 1970-01-01
        • 2014-03-01
        • 1970-01-01
        • 2011-01-19
        相关资源
        最近更新 更多