用Java解压缩PHP的gzcompress

时间:2014-09-30 01:24:03

标签: java php compression gzip zlib

我试图解压缩最初在PHP中压缩的Java中的json对象。以下是如何将其压缩为PHP:

function zip_json_encode(&$arr) {
  $uncompressed = json_encode($arr);
  return pack('L', strlen($uncompressed)).gzcompress($uncompressed);
}

并解码(再次在PHP中):

function unzip_json_decode(&$data) {
  $uncompressed = @gzuncompress(substr($data,4));
  return json_decode($uncompressed, $array_instead_of_object);
}

它被放入MySQL,现在必须通过Java从数据库中取出。我们从ResultSet中取出它:

String field = rs.getString("field");

然后我将该字符串传递给解压缩方法。这就是它崩溃的地方。

private String decompressHistory(String historyString) throws SQLException {
    StringBuffer buffer = new StringBuffer();
    try {
        byte[] historyBytes = historyString.substring(4).getBytes();
        ByteArrayInputStream bin = new ByteArrayInputStream(historyBytes);
        InflaterInputStream in = new InflaterInputStream(bin, new Inflater(true));
        int len;
        byte[] buf = new byte[1024];
        while ((len = in.read(buf)) != -1) {
            // buf should be decoded, right?
        }

    } catch (IOException e) {
        e.getStackTrace();
    }
    return buffer.toString();

}

不太确定这里出了什么问题,但任何指针都会受到赞赏!

3 个答案:

答案 0 :(得分:1)

您需要摆脱true中的Inflater(true)。仅使用Inflater()true使其期望原始收缩数据。没有true,它期待zlib包装的deflate数据。 PHP的gzcompress()生成zlib包装的deflate数据。

答案 1 :(得分:1)

Gzip压缩数据是二进制,byte []。使用String,Unicode文本,不仅需要转换,而且还有问题。

例如,这涉及转换:

byte[] historyBytes = historyString.substring(4).getBytes();
byte[] historyBytes = historyString.substring(4).getBytes("ISO-8859-1");

第一个版本使用默认平台编码,使应用程序不可移植。

第一个待办事项是将数据库中的二进制数据用作VARBINARY或BLOB。

ImputStream field = rs.getBinaryStream("field");
try (InputStream in = new GZIPInputStream(field)) {
    ...
}

或者是这样。记住另一个答案。

答案 2 :(得分:0)

最后,上述解决方案都没有奏效,但两者都有优点。当我们从mysql中提取数据并将其转换为字节时,我们有许多丢失的字符字节(67)。这使得无法在java端解压缩。至于上面的答案。标记是正确的,gzcompress()使用zlib,因此你应该在Java中使用Inflater()类。

Joop是正确的,数据转换是错误的。我们的表太大了,无法将其转换为varbinary或blob。 可能已经解决了问题,但对我们没有用。我们最终让java向我们的PHP应用程序发出请求,然后简单地在PHP端解压缩压缩数据。这很好用。希望这对任何偶然发现它的人都有帮助。