HTTP соединение закрыто при чтении сжатых входных потоков GZIP

Мне нужно обрабатывать большие сжатые gzip текстовые файлы.

InputStream is = new GZIPInputStream(new FileInputStream(path));
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null) {
    someComputation();  
}

Этот код работает, если я не выполняю длинных вычислений внутри цикла (что мне и нужно). Но добавление всего нескольких миллисекунд сна для каждой строки приводит к аварийному завершению работы программы с исключением java.util.zip.ZipException. Сообщение об исключении каждый раз отличается ("недопустимый код литерала / длины", "недопустимый тип блока", "недопустимая длина хранимого блока").
Таким образом, кажется, что поток становится поврежденным, когда я не читаю его достаточно быстро.

Я могу разархивировать файлы без проблем. Я также попробовал GzipCompressorInputStream из Apache Commons Compress с тем же результатом.
В чем здесь проблема и как ее можно решить?

обновление 1

Я думал, что исключил это, но проведя больше тестов, я обнаружил, что проблема ограничена потоковой передачей файлов из Интернета.

полный пример:

URL source = new URL(url);      
HttpURLConnection connection = (HttpURLConnection) source.openConnection();
connection.setRequestMethod("GET"); 
connection.setRequestProperty("Accept", "gzip, deflate"); 
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream())));        
String line;
while ((line = br.readLine()) != null) { //exception is thrown here
    Thread.sleep(5);  
}

Интересно, что когда я печатал номера строк, я обнаружил, что это всегда одна из тех же четырех или пяти разных строк, где происходит сбой моей программы.


обновление 2

Вот полный пример, содержащий фактический файл:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.zip.GZIPInputStream;


public class TestGZIPStreaming {

    public static void main(String[] args) throws IOException {

        URL source = new URL("http://tools.wmflabs.org/wikidata-exports/rdf/exports/20151130/wikidata-statements.nt.gz");      
        HttpURLConnection connection = (HttpURLConnection) source.openConnection();
        connection.setRequestMethod("GET"); 
        connection.setRequestProperty("Accept", "gzip, deflate"); 
        BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream())));       

        String line;
        int n = 0;

        while ((line = br.readLine()) != null) { //exception is thrown here
            Thread.sleep(10);  
            System.out.println(++n);
        }

    }

}

Для этого файла сбои появляются вокруг строки 90000.

Чтобы исключить проблему тайм-аута, я попытался connection.setReadTimeout(0) - без эффекта.

Вероятно, это проблема сети. Но так как я могу загрузить файл в браузере, должен быть способ с этим справиться.

обновление 3

Я попытался подключиться с помощью Apache HttpClient.

HttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet("http://tools.wmflabs.org/wikidata-exports/rdf/exports/20151130/wikidata-statements.nt.gz");
get.addHeader("Accept-Encoding", "gzip");
HttpResponse response = client.execute(get);
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new BufferedInputStream(response.getEntity().getContent()))));

Теперь я получаю следующее исключение, которое, вероятно, более полезно.

org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 3850131; received: 1581056
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)

Опять же, должен быть способ решения проблемы, поскольку я могу загрузить файл в браузере и распаковать его без каких-либо проблем.

0 ответов

Другие вопросы по тегам