У меня возникли проблемы со сжатием некоторых веб-сайтов. Следующий код должен работать нормально, но выбрасывает EOFException
. Все основные браузеры могут загружать сайт, и у меня также нет проблем с использованием curl с gzip.java.io.EOFException: Неожиданный конец входного потока ZLIB, считываемого 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.
Заранее спасибо!
Edit: я мог бы просто прочитать поток сам и глотать исключение, но в данный момент происходит исключение, я мог бы потерять 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, но это ОЧЕНЬ МЕДЛЕННО.
Итак, как получить все корректные считываемые данные без потери производительности?
Вы, по крайней мере, можете прочитать несколько строк? Если да, значит, они не возвращают gzipped-данные, хотя я бы ожидал, что сообщение об ошибке будет «Не в формате GZIP» – Dici
Если я прочитаю вручную с помощью буфера, я вижу, что он читает до конца, а затем бросает это исключение ... Я мог бы проглотить его и просто использовать байты, которые были прочитаны, но документ может быть не полным, а – Ph3n1x
Кстати, имя всех этих сайтов кажется подозрительным чуваком ... – Dici