解压缩PHP';s的gzcompression


Decompressing PHP's gzcompress in Java

我正在尝试用Java解压缩一个json对象,该对象最初是用PHP压缩的。以下是如何将其压缩为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();
}

不太确定这里出了什么问题,但任何建议都将不胜感激!

您需要去掉Inflater(true)中的true。仅使用Inflater()true使其期望原始放气数据。如果没有true,它将期望使用zlib封装的deflate数据。PHP的gzcompress()生成zlib封装的deflate数据。

Gzipped数据是二进制的,byte[]。使用字符串,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)) {
    ...
}

或者是这样。注意另一个答案。

最后,上述两种解决方案都不起作用,但都有优点。当我们从mysql中提取数据并将其转换为字节时,我们有许多缺失的字符字节(67)。这使得无法在java端进行解压缩。至于上面的答案。标记gzcompress()使用zlib是正确的,因此您应该在Java中使用充气器()类。

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