2

一部の Web サイトの圧縮に問題があります。次のコードは問題なく動作するはずですが、EOFException. すべての主要なブラウザーでサイトを読み込むことができ、gzip で curl を使用しても問題ありません。

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 エンコーディングに問題がある Web サイトはこれだけではありません。私も問題を抱えています

  • 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 ですが、それは非常に遅いです。

では、パフォーマンスを落とさずにすべての正しい読み取り可能なデータを取得するにはどうすればよいでしょうか?

4

2 に答える 2