一部の 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 ですが、それは非常に遅いです。
では、パフォーマンスを落とさずにすべての正しい読み取り可能なデータを取得するにはどうすればよいでしょうか?