36

我正在尝试将 HTTP 响应的 gzip 压缩正文转换为纯文本。我已获取此响应的字节数组并将其转换为 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);
}
4

8 回答 8

50

要解码来自 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);
}
于 2010-09-02T13:17:07.467 回答
34

InputStream您应该以 an而不是 as的形式获得响应byte[]。然后你可以解压缩它 usingGZIPInputStream并将其作为字符数据读取InputStreamReader,最后将其作为字符数据写入Stringusing StringWriter

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();
于 2010-09-02T13:17:02.507 回答
10

使用 try-with-resources 习惯用法(在退出块时自动关闭在 try(...) 中打开的任何资源)以使代码更清晰。

使用 Apache IOUtils 使用默认的 CharSet 将 inputStream 转换为 String。

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);
    }
}
于 2017-01-23T19:26:47.867 回答
2

使用 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 uncompressedContent = new String(decompressContent(inputStream));
于 2015-05-14T19:41:15.257 回答
1

您可以使用StringWriter写入 String

于 2010-09-02T13:15:47.593 回答
1

GZip wiki是一种文件格式和用于文件压缩和解压缩的软件应用程序。gzip 是一个单文件/流无损数据压缩实用程序,其中生成的压缩文件通常具有后缀.gz

字符串(Plain)➢ 字节 ➤ GZip 数据(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 字节(Compress)➥ 文件(*.gz)➥ 字符串(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;
}
于 2020-10-09T10:57:38.067 回答
0
import java.io.*;
import java.util.zip.*;

public class Ex1 {

    public static void main(String[] args) throws Exception{
        String str ;

        H h1 = new H();
        h1.setHcfId("PH12345658");
        h1.setHcfName("PANA HEALTH ACRE FACILITY");

        str = h1.toString();
        System.out.println(str);

        if (str == null || str.length() == 0) {
            return ;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream(str.length());
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(str.getBytes());
        gzip.close();
        out.close();

        String s =  out.toString() ;
        System.out.println( s );
        byte[] ba = out.toByteArray();
        System.out.println( "---------------BREAK-------------" );

        ByteArrayInputStream in = new ByteArrayInputStream(ba);
        GZIPInputStream gzis = new GZIPInputStream(in);
        InputStreamReader reader = new InputStreamReader(gzis);
        BufferedReader pr = new BufferedReader(reader);

        String readed;
        while ((readed = pr.readLine()) != null) {
            System.out.println(readed);
        }

        //Close all the streams
    }

}
于 2014-09-25T07:09:42.753 回答
0

你也可以

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

AutoClosable 是个好东西 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

于 2017-04-07T12:01:47.813 回答