8

我正在尝试使用以下 Java 代码来压缩和解压缩字符串。但是从新的 ByteArrayInputStream 对象中创建新的 GZipInputStream 对象的行会引发“java.util.zip.ZipException: Not in GZIP format”异常。有谁知道如何解决这个问题?

        String orig = ".............";

        // compress it
        ByteArrayOutputStream baostream = new ByteArrayOutputStream();
        OutputStream outStream = new GZIPOutputStream(baostream);
        outStream.write(orig.getBytes());
        outStream.close();
        String compressedStr = baostream.toString();

        // uncompress it
        InputStream inStream = new GZIPInputStream(new ByteArrayInputStream(compressedStr.getBytes()));
        ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
        byte[] buffer = new byte[8192];
        int len;
        while((len = inStream.read(buffer))>0)
            baoStream2.write(buffer, 0, len);
        String uncompressedStr = baoStream2.toString();
4

3 回答 3

10

混合Stringbyte[]; 那永远不适合。并且仅适用于具有相同编码的相同操作系统。并非每个byte[]都可以转换为 a String,并且转换回可能会给出其他字节。

compressedBytes不需要代表一个字符串。

getBytes在和中显式设置编码new String

    String orig = ".............";

    // Compress it
    ByteArrayOutputStream baostream = new ByteArrayOutputStream();
    OutputStream outStream = new GZIPOutputStream(baostream);
    outStream.write(orig.getBytes("UTF-8"));
    outStream.close();
    byte[] compressedBytes = baostream.toByteArray(); // toString not always possible

    // Uncompress it
    InputStream inStream = new GZIPInputStream(
            new ByteArrayInputStream(compressedBytes));
    ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int len;
    while ((len = inStream.read(buffer)) > 0) {
        baoStream2.write(buffer, 0, len);
    }
    String uncompressedStr = baoStream2.toString("UTF-8");

    System.out.println("orig: " + orig);
    System.out.println("unc:  " + uncompressedStr);
于 2013-01-22T20:06:49.217 回答
4

Joop 似乎有解决方案,但我觉得我必须添加这个:一般的压缩,特别是 GZIP 会产生二进制流。你不能 尝试从这个流中构造一个字符串——它会中断

如果您需要将其转换为纯文本表示,请查看 Base64 编码、十六进制编码、哎呀,甚至是简单的二进制编码。

简而言之,String 对象用于人类阅读的内容。字节数组(和许多其他东西)用于机器读取的东西。

于 2013-01-22T20:23:39.620 回答
0

您使用默认平台编码(可能是 UTF-8)将 baostream 编码为字符串。您应该使用 baostream.getBytes() 处理二进制数据,而不是字符串。

如果您坚持使用字符串,请使用 8 位编码,eh baostream.toString("ISO-8859-1"),并使用相同的字符集将其读回。

于 2013-01-22T19:55:21.660 回答