我正在将一个Python应用程序移植到Android,并且在某些时候,该应用程序必须与Web服务通信,并向其发送压缩数据。
为此,它使用下一个方法:
def stuff(self, data):
"Convert into UTF-8 and compress."
return zlib.compress(simplejson.dumps(data))
我正在使用下一种方法尝试在Android中模拟此行为:
private String compressString(String stringToCompress)
{
Log.i(TAG, "Compressing String " + stringToCompress);
byte[] input = stringToCompress.getBytes();
// Create the compressor with highest level of compression
Deflater compressor = new Deflater();
//compressor.setLevel(Deflater.BEST_COMPRESSION);
// Give the compressor the data to compress
compressor.setInput(input);
compressor.finish();
// Create an expandable byte array to hold the compressed data.
// You cannot use an array that's the same size as the orginal because
// there is no guarantee that the compressed data will be smaller than
// the uncompressed data.
ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
// Compress the data
byte[] buf = new byte[1024];
while (!compressor.finished())
{
int count = compressor.deflate(buf);
bos.write(buf, 0, count);
}
try {
bos.close();
} catch (IOException e)
{
}
// Get the compressed data
byte[] compressedData = bos.toByteArray();
Log.i(TAG, "Finished to compress string " + stringToCompress);
return new String(compressedData);
}
但是来自服务器的HTTP响应不正确,我想这是因为Java中的压缩结果与Python中的结果不同。
我用zlib.compress和deflate运行了一个小测试压缩“a”。
Python,zlib.compress() - > X%9CSJT%02%00%01M%00%A6
Android,Deflater.deflate - > H%EF%BF%BDK%04%00%00B 00B%
如何压缩Android中的数据以在Python中获取相同的zlib.compress()值?
非常感谢任何帮助,指导或指针!
答案 0 :(得分:7)
压缩和放气是不同的压缩算法,所以答案是它们不兼容。作为差异的一个例子,这里使用两个算法通过Tcl压缩'a':
% binary encode hex [zlib compress a]
789c4b040000620062
% binary encode hex [zlib deflate a]
4b0400
你的python代码确实在做压缩。并且android代码正在进行deflate,但是你也获得了Android版本前面的UTF-8字节顺序标记(\ xef \ xbf \ xbf)
您可以使用python:
发出deflate数据def deflate(data):
zobj = zlib.compressobj(6,zlib.DEFLATED,-zlib.MAX_WBITS,zlib.DEF_MEM_LEVEL,0)
zdata = zobj.compress(data)
zdata += zobj.flush()
return zdata
>>> deflate("a")
'K\x04\x00'
答案 1 :(得分:2)
虽然它们不是完全相同的算法,但似乎它们完全兼容(这意味着如果你使用Deflater.deflate压缩,例如,你可以使用zlib正确地解压缩它)。
导致我的问题的原因是POST中的所有表单变量都需要进行百分比转义,并且Android应用程序没有这样做。在发送数据之前将数据编码到Base64,并在使用zlib解压缩之前修改服务器以使用Base64解码它解决了这个问题。
答案 2 :(得分:0)
byte[] input = stringToCompress.getBytes("utf-8");
有帮助吗?如果您的平台的默认编码不是UTF-8,这将强制编码String - >使用UTF-8的字节数。此外,您创建new String
的代码的最后一行也是如此 - 您可能希望将UTF-8明确指定为解码字符集。