我有以下代码,当使用错误调用时失败:
qUncompress: could not allocate enough memory to uncompress data
代码:
QString decStage3 ( QByteArray s )
{
printf ( "3a: length in %d\n", s.length());
QByteArray bData = QByteArray::fromHex(s );
printf ( "3b: length ba %d\n", bData.length());
printf ( "3c: ba [%s]\n", qPrintable(bData.toHex()));
printf ( "3d: mem [%d]\n", bData.capacity() );
QByteArray dS = qUncompress( bData );
// QByteArray::fromHex(s.toLatin1());
return (dS.data());
}
示例输入为“789C0B492D2E5170492C490400101E033B”(==“测试数据”)。
更新:根据切尔诺贝利的建议,我决定添加如下直接测试:
void tst ( QByteArray b0 )
{
QByteArray b1 = qCompress (b0);
printf ( "[%s] %d = [%s] %d\n", qPrintable(b0), b0.length(), qPrintable(b1.toHex()), b1.length());
QByteArray b2 = qUncompress (b1);
printf ( "uncomp = [%s]\n", qPrintable(b2));
}
然后测试:
tst ("Hello");
tst ("Hello World");
tst ("Hello World Nice To See You");
这给出了以下内容:
[Hello] 5 = [00000005789cf348cdc9c90700058c01f5] 17
uncomp = [Hello]
[Hello World] 11 = [0000000b789cf348cdc9c95708cf2fca490100180b041d] 23
uncomp = [Hello World]
[Hello World Nice To See You] 27 = [0000001b789cf348cdc9c95708cf2fca4951f0cb4c4e5508c957084e4d5588cc2f050082f70939] 39
uncomp = [Hello World Nice To See You]
请注意,前8个字节现在看起来保持原始字符串的长度(十六进制)。我之前没有遇到过这种行为。我可以修改源程序以包含它(来自另一个系统,使用Java),但有没有办法避免必须这样做?
答案 0 :(得分:1)
通过在zip数据之前预先设置虚拟长度(从789c开始)来修复(或者更确切地说是工作):
QString decStage3 ( QByteArray s )
{
printf ( "3a: length in %d\n", s.length());
QByteArray bData = QByteArray::fromHex("00004000") + QByteArray::fromHex(s );
printf ( "3b: length ba %d\n", bData.length());
printf ( "3c: ba [%s]\n", qPrintable(bData.toHex()));
printf ( "3d: mem [%d]\n", bData.capacity() );
QByteArray dS = qUncompress( bData );
// QByteArray::fromHex(s.toLatin1());
return (dS.data());
}
这是我声明bData的行,在" 00004000"之前加上它。评估为16K。事实证明,虽然在压缩时它表示未压缩数据的长度,但在非压缩时它实际上并不需要是准确的长度。所以,假设这更多地与内部使用的内存抓取进行解压缩,我选择了16K,因为这对于我们期望的数据来说已经足够了。