java.io.EOFException:读取gzip编码网站的ZLIB输入流的意外结束

时间:2016-08-09 23:01:59

标签: java gzip compression gzipinputstream

我在压缩某些网站时遇到了麻烦。以下代码应该可以正常工作,但会抛出EOFException。所有主流浏览器都可以加载网站,我也没有问题使用curl和gzip。

public static void main(String[] args) throws IOException {
    URL url = new URL("http://www.ddanzi.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty("Accept-Encoding", "gzip");
    System.out.println("Encoding: " + connection.getContentEncoding());
    System.out.println("Bytes: " + IOUtils.toByteArray(new GZIPInputStream(connection.getInputStream())).length);
}

这将是输出:

Encoding: gzip
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
    at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
    at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
    at java.io.FilterInputStream.read(FilterInputStream.java:107)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1792)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744)
    at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:462)
    at Test.main(Test.java:18)

这不是我遇到gzip编码问题的唯一网站。

我也有问题
  • mgtv.com
  • yxdown.com
  • weather.com.cn
  • ebrun.com

我做错了吗?

我的系统是Win7 x64,Java 8 Update 102。

提前致谢!

编辑:我可以自己读取流并吞下异常,但是当异常发生时,我可能会丢失 bufferSize 字节并且损坏了/不完整的文件有没有办法克服这个问题(除了将 bufferSize 设置为1)?

编辑2:作为获取字节直到异常发生的解决方法,可以例如像这样阅读流:

byte[] buffer = new byte[bufferSize];
InputStream inputStream = connection.getInputStream():
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
    while(true) {
        int read = inputStream.read(buffer);
        if (read == -1) break;
        baos.write(buffer, 0, read);
    }
}catch(Exception e) {
    // Just swallow or Log or something...
}
byte[] result = baos.toByteArray();

但问题是,如何选择 bufferSize ?当它是例如设置为1000,在某些时候,例如当读取当前1000字节的最后一个异常发生时,我将丢失所有正确读取的999字节。完整性的完美价值是1,但这非常慢。

那么,如何在不失去性能的情况下获得所有正确的可读数据?

2 个答案:

答案 0 :(得分:2)

您看到该异常的原因是服务器响应不正确。请尝试使用http://www.google.com,您将看到您的代码正常工作(您可能会得到302响应,只需按照重定向)。

您可以做的是让您的代码更加健壮。请记住,服务器可以并将响应任何内容。例如,您可能要求gzip编码,但服务器可能会选择返回纯文本。代码需要处理这种情况。

答案 1 :(得分:1)

由于某些原因,列表中的某些网站会返回截断的gzip内容。您可以使用curl

手动验证它
curl -H "Accept-Encoding: gzip" http://www.ebrun.com/ 2>/dev/null \
  | zcat >/dev/null 
gzip: skipping: <stdin>: corrupted -- missing trailer

所以你的代码是有效的。你应该责怪网站。