java.io.EOFException : Unexpected end of ZLIB input stream reading gzip encoded website

标签 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
  • 天气网
  • 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,但这非常慢。

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

最佳答案

您看到该异常的原因是服务器响应不正确。请尝试 http://www.google.com,您会发现您的代码可以正常工作(您可能会收到 302 响应,只需遵循重定向即可)。

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

关于java.io.EOFException : Unexpected end of ZLIB input stream reading gzip encoded website,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38861764/

相关文章:

python - 读取当前正在写入的 gzip 文件

compression - 创建没有文件夹结构的 tar 文件

groovy - 如何使用 SOAPUI 解压缩 GET 响应

java - 如何在java中使用HTTPS wsdl文件而不下载到本地计算机

PHP 手动 GZip 编码

java - 如何从数据库中的表中选择列,其中日期时间是java中的某个特定日期?

php - 我如何在 Zend Framework 中将我的响应设为 "gzip"?

.NET DeflateStream 与 linux zlib 的区别

java - 我的自定义 JComponent 没有显示?

java - google-api-client 和 google-api-services 之间的版本兼容性