【问题标题】:GZIP decompress string and byte conversionGZIP解压字符串和字节转换
【发布时间】:2012-06-11 05:41:01
【问题描述】:

我的代码有问题:

private static String compress(String str)
{
    String str1 = null;
    ByteArrayOutputStream bos = null;
    try
    {
        bos = new ByteArrayOutputStream();
        BufferedOutputStream dest = null;

        byte b[] = str.getBytes();
        GZIPOutputStream gz = new GZIPOutputStream(bos,b.length);
        gz.write(b,0,b.length);
        bos.close();
        gz.close();

    }
    catch(Exception e) {
        System.out.println(e);
        e.printStackTrace();
    }
    byte b1[] = bos.toByteArray();
    return new String(b1);
}

private static String deCompress(String str)
{
    String s1 = null;

    try
    {
        byte b[] = str.getBytes();
        InputStream bais = new ByteArrayInputStream(b);
        GZIPInputStream gs = new GZIPInputStream(bais);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int numBytesRead = 0;
        byte [] tempBytes = new byte[6000];
        try
        {
            while ((numBytesRead = gs.read(tempBytes, 0, tempBytes.length)) != -1)
            {
                baos.write(tempBytes, 0, numBytesRead);
            }

            s1 = new String(baos.toByteArray());
            s1= baos.toString();
        }
        catch(ZipException e)
        {
            e.printStackTrace();
        }
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    return s1;
}

public String test() throws Exception
    {
        String str = "teststring";
        String cmpr = compress(str);
        String dcmpr = deCompress(cmpr);
}

这段代码抛出 java.io.IOException: unknown format (magic number ef1f)

GZIPInputStream gs = new GZIPInputStream(bais);

事实证明,在转换字节时new String (b1)byte b [] = str.getBytes () 字节被“宠坏了”。在该行的输出处,我们已经有了更多字节。如果您避免转换为字符串并使用字节进行操作 - 一切正常。对不起我的英语。


public String unZip(String zipped) throws DataFormatException, IOException {
    byte[] bytes = zipped.getBytes("WINDOWS-1251");
    Inflater decompressed = new Inflater();
    decompressed.setInput(bytes);

    byte[] result = new byte[100];
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    while (decompressed.inflate(result) != 0)
        buffer.write(result);

    decompressed.end();

    return new String(buffer.toByteArray(), charset);
}

我使用这个函数来解压服务器响应。感谢您的帮助。

【问题讨论】:

    标签: java gzip gzipoutputstream


    【解决方案1】:

    你有两个问题:

    • 您正在使用默认字符编码将原始字符串转换为字节。这将因平台而异。最好指定编码 - UTF-8 通常是个好主意。
    • 您试图通过调用String(byte[]) 构造函数将压缩结果的不透明二进制数据表示为字符串。该构造函数用于编码文本的数据......这不是。您应该为此使用 base64。有一个public domain base64 library 让这很容易。 (或者,根本不将压缩数据转换为文本 - 只需返回一个字节数组。)

    从根本上说,您需要了解文本和二进制数据的不同之处——当您想要在两者之间进行转换时,您应该谨慎操作。如果你想在字符串中表示“非文本”二进制数据(即 不是编码文本的直接结果的字节),你应该使用 base64 或 hex 之类的东西。当您想将字符串编码为二进制数据(例如,将一些文本写入磁盘)时,您应该仔细考虑使用哪种编码。如果另一个程序要读取您的数据,您需要确定它期望的编码 - 如果您自己可以完全控制它,我通常会选择 UTF-8。

    此外,您的代码中的异常处理很差:

    • 你几乎不应该抓到Exception;捕获更具体的异常
    • 您不应该只是捕获异常并继续执行,就好像它从未发生过一样。如果你不能真正处理异常并且仍然​​成功地完成你的方法,你应该让异常在堆栈中冒泡(或者可能捕获它并将它包装在一个更适合你的抽象的异常类型中)

    【讨论】:

    • 我使用 default_charset() == "UTF-8"。这只是测试。
    • @AlexandrErofeev:当有人阅读你正在使用的编码时,它不会很清楚。 IMO 最好明确说明。 (如果只是作为测试,完全去掉所有的异常处理,让所有的方法抛出IOException——这样会简化代码。)
    【解决方案2】:

    当你 GZIP 压缩数据时,你总是得到二进制数据。此数据无法转换为字符串,因为它不是有效的字符数据(任何编码)。

    所以你的 compress 方法应该返回一个字节数组,而你的 decompress 方法应该把一个字节数组作为它的参数。

    另外,我建议你在压缩前将字符串转换为字节数组以及将解压后的数据再次转换为字符串时使用显式编码。

    【讨论】:

    • 这只是一个测试。事实上,从服务器,我得到了一个 json 字符串,它是键“zip”。包含压缩数据。我可以将键的内容作为字符串获取。然后我需要提取这些信息。
    • @AlexandrErofeev:所有这些都是您应该包含在问题中的信息。我怀疑 JSON 包含 base64 编码的数据......这就是我希望它代表二进制数据的方式。
    • JSON 不能直接包含二进制数据。因此,如果密钥是 GZIP 编码的,它可能也是 Base64 编码的,以将二进制数据转换为 JSON 可以包含的字符串。您可能应该添加一个带有问题关键的 JSON 示例。
    【解决方案3】:

    当你 GZIP 压缩数据时,你总是得到二进制数据。这个数据 无法转换为字符串,因为它不是有效的字符数据(在 任何编码)。

    Codo 是对的,非常感谢您启发我。我试图解压缩一个字符串(从二进制数据转换而来)。我修改的是直接在我的 http 连接返回的输入流上使用 InflaterInputStream。 (我的应用正在检索大量 JSON 字符串)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 2017-10-10
      • 1970-01-01
      • 2011-08-18
      • 2011-04-07
      • 1970-01-01
      • 2013-12-15
      相关资源
      最近更新 更多