GZIPInputStream в строку

Я пытаюсь преобразовать сжатое тело HTTP-ответа в открытый текст. Я взял байтовый массив этого ответа и преобразовал его в ByteArrayInputStream. Затем я преобразовал это в GZIPInputStream. Теперь я хочу прочитать GZIPInputStream и сохранить окончательное распакованное тело ответа HTTP в виде строки с открытым текстом.

Этот код сохранит окончательное распакованное содержимое в OutputStream, но я хочу сохранить содержимое как строку:

public static int sChunk = 8192;
ByteArrayInputStream bais = new ByteArrayInputStream(responseBytes);
GZIPInputStream gzis = new GZIPInputStream(bais);
byte[] buffer = new byte[sChunk];
int length;
while ((length = gzis.read(buffer, 0, sChunk)) != -1) {
        out.write(buffer, 0, length);
}

person Matt    schedule 02.09.2010    source источник
comment
Как я уже сказал в вашем другом вопросе (stackoverflow.com/questions/3621750), вам необходимо использовать InputStreamReader.   -  person Jon Skeet    schedule 02.09.2010
comment
посмотрите на эту ссылку stackoverflow.com/q/6717165/779408   -  person Bobs    schedule 15.01.2013
comment
Отвечает ли это на ваш вопрос? Распаковать строку GZip в Java   -  person Yash    schedule 09.10.2020


Ответы (7)


Чтобы декодировать байты из InputStream, вы можете использовать InputStreamReader. Затем BufferedReader позволит вам читать ваш поток построчно.

Ваш код будет выглядеть так:

ByteArrayInputStream bais = new ByteArrayInputStream(responseBytes);
GZIPInputStream gzis = new GZIPInputStream(bais);
InputStreamReader reader = new InputStreamReader(gzis);
BufferedReader in = new BufferedReader(reader);

String readed;
while ((readed = in.readLine()) != null) {
    System.out.println(readed);
}
person Vivien Barousse    schedule 02.09.2010
comment
И не забудьте указать кодировку в конструкторе ISR для правильной интерпретации байтов! :) - person helios; 02.09.2010
comment
Помимо потенциальной ошибки кодирования, также обратите внимание, что этот подход поглощает новые строки. Поэтому, если вы хотите сохранить новые строки в выводе, вам действительно нужно явно добавить их в output самостоятельно (например, с помощью PrintWriter#println() или BufferedWriter#newLine()). Или просто используйте подход цикла char[] buffer, как показано в другом ответе, который не принимает новые строки. - person BalusC; 03.12.2012

Вам лучше получить ответ в виде _1 _ вместо byte[]. Затем вы можете разархивировать его с помощью GZIPInputStream и считайте его как символьные данные с помощью InputStreamReader и наконец, запишите его как символьные данные в String, используя _6 _ .

String body = null;
String charset = "UTF-8"; // You should determine it based on response header.

try (
    InputStream gzippedResponse = response.getInputStream();
    InputStream ungzippedResponse = new GZIPInputStream(gzippedResponse);
    Reader reader = new InputStreamReader(ungzippedResponse, charset);
    Writer writer = new StringWriter();
) {
    char[] buffer = new char[10240];
    for (int length = 0; (length = reader.read(buffer)) > 0;) {
        writer.write(buffer, 0, length);
    }
    body = writer.toString();
}

// ...

Смотрите также:


Если ваша конечная цель - разобрать ответ как HTML, я настоятельно рекомендую просто использовать для этого HTML-анализатор, например Jsoup. Тогда это так же просто, как:

String html = Jsoup.connect("http://google.com").get().html();
person BalusC    schedule 02.09.2010

Используйте идиому try-with-resources (которая автоматически закрывает все ресурсы, открытые в try (...) при выходе из блока), чтобы сделать код более чистым.

Используйте Apache IOUtils для преобразования inputStream в String с использованием CharSet по умолчанию.

import org.apache.commons.io.IOUtils;
public static String gzipFileToString(File file) throws IOException {
    try(GZIPInputStream gzipIn = new GZIPInputStream(new FileInputStream(file))) {
        return IOUtils.toString(gzipIn);
    }
}
person Misam Abbas    schedule 23.01.2017
comment
Вам действительно следует добавить некоторые пояснения относительно того, почему этот код должен работать - вы также можете добавлять комментарии в сам код - в его текущей форме он не предоставляет никаких объяснений, которые могли бы помочь остальной части сообщества понять, что вы сделали для решения /ответь на вопрос. - person ishmaelMakitla; 23.01.2017
comment
Это самый простой ответ. Зачем беспокоиться об обработке буферов, байтов, закрытии и т. Д., Когда это может быть 2-строчный? Также вряд ли каждый проект в наши дни будет где-то использовать IOUtils. - person membersound; 08.03.2018

Используйте Apache Commons для преобразования GzipInputStream в byteArray.

import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.IOUtils;

public static byte[] decompressContent(byte[] pByteArray) throws IOException {
        GZIPInputStream gzipIn = null;
        try {
            gzipIn = new GZIPInputStream(new ByteArrayInputStream(pByteArray));
            return IOUtils.toByteArray(gzipIn);
        } finally {
            if (gzipIn != null) {
                gzipIn.close();
            }
        }

Чтобы преобразовать несжатое содержимое массива байтов в String, сделайте что-то вроде этого:

String uncompressedContent = new String(decompressContent(inputStream));
person ChaitanyaBhatt    schedule 14.05.2015

Вы можете использовать StringWriter для записи Нить

person Gopi    schedule 02.09.2010

GZip wiki - это формат файла и программное приложение, используемое для сжатия и распаковки файлов. gzip - это утилита сжатия данных без потерь для одного файла / потока, где результирующий сжатый файл обычно имеет суффикс .gz

Строка(Plain) ➢ Байты ➤ GZip-Data(Compress) ➦ Байты ➥ Строка(Decompress)

String zipData = "Hi Stackoverflow and GitHub";
        
// String to Bytes
byte[] byteStream = zipData.getBytes();
System.out.println("String Data:"+ new String(byteStream, "UTF-8"));

// Bytes to Compressed-Bytes then to String.
byte[] gzipCompress = gzipCompress(byteStream);
String gzipCompressString = new String(gzipCompress, "UTF-8");
System.out.println("GZIP Compressed Data:"+ gzipCompressString);

// Bytes to DeCompressed-Bytes then to String.
byte[] gzipDecompress = gzipDecompress(gzipCompress);
String gzipDecompressString = new String(gzipDecompress, "UTF-8");
System.out.println("GZIP Decompressed Data:"+ gzipDecompressString);

GZip-Bytes(Compress) ➥ Файл (*.gz) ➥ String(Decompress)

GZip Расширение имени файла .gz, тип интернет-носителя - application/gzip.

File textFile = new File("C:/Yash/GZIP/archive.gz.txt");
File zipFile = new File("C:/Yash/GZIP/archive.gz");
org.apache.commons.io.FileUtils.writeByteArrayToFile(textFile, byteStream);
org.apache.commons.io.FileUtils.writeByteArrayToFile(zipFile, gzipCompress);

FileInputStream inStream = new FileInputStream(zipFile);
byte[] fileGZIPBytes = IOUtils.toByteArray(inStream);
byte[] gzipFileDecompress = gzipDecompress(fileGZIPBytes);
System.out.println("GZIPFILE Decompressed Data:"+ new String(gzipFileDecompress, "UTF-8"));

Следующие функции используются для сжатия и распаковки.

public static byte[] gzipCompress(byte[] uncompressedData) {
    byte[] result = new byte[]{};
    try (
        ByteArrayOutputStream bos = new ByteArrayOutputStream(uncompressedData.length);
        GZIPOutputStream gzipOS = new GZIPOutputStream(bos)
        ) {
        gzipOS.write(uncompressedData);
        gzipOS.close(); // You need to close it before using ByteArrayOutputStream
        result = bos.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}

public static byte[] gzipDecompress(byte[] compressedData) {
    byte[] result = new byte[]{};
    try (
        ByteArrayInputStream bis = new ByteArrayInputStream(compressedData);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        GZIPInputStream gzipIS = new GZIPInputStream(bis)
        ) {
        //String gZipString= IOUtils.toString(gzipIS);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = gzipIS.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        result = bos.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
person Yash    schedule 09.10.2020

вы также можете сделать

try (GZIPInputStream gzipIn = new GZIPInputStream(new ByteArrayInputStream(pByteArray)))
{
....
}

AutoClosable - это хорошо. https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

person Alexander Byrd    schedule 07.04.2017