我试图解压缩最初在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();
}
不太确定这里出了什么问题,但任何指针都会受到赞赏!
答案 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端解压缩压缩数据。这很好用。希望这对任何偶然发现它的人都有帮助。