我正在尝试用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数据。
例如,这涉及转换:
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端解包压缩数据。这很有效。希望这对其他偶然发现它的人有帮助。