因为QT也是用zlib库的,所以理论上数据是可以直接互通的,但现实是残酷的。通过对qCompress和compress压缩的数据进行打印,可以知道qCompress比compress的数据长四个字节,而这四个字节的内容则未压缩前的数据长度, 这四个字节在数据的最前面。通过内存观察到,qCompress这个四个字节的存储方式是大端在前,而WINDOWS系统存储方式是小端在前,所以需要对这四个字节进行增删就可以实现QT和zlib相互调用。
1、QT的qCompress压缩的数据调zlib的uncompress解压
只要把qCompress压缩的数据的前四位不要了,然后直接把后面的数据传过去,然后数据长度-4。
int QtToZLIBUncompr(char *pDest, uLongf *pDestLen, const char *pQtComprData, uLongf dataLen)
{
return uncompress((Byte *)pDest, pDestLen, (const Bytef*)pQtComprData + 4, dataLen - 4);
}
QT环境测试:
QString test = "asdf451A21D54sadAS";
char uncompr[100] = {0};
uLong uncomprLen = 100;
QByteArray qbyteArray = qCompress(test.toLocal8Bit());
int err = QtToZLIBUncompr(uncompr, &uncomprLen, qbyteArray.data(), qbyteArray.length())
//如果不初始化,且数据是字符串,记得在返回解压长度uncomprLen的下标位置添加结束符'\0'或者赋值0。
//uncompr[uncomprLen] = 0;
if(err)
qDebug() << "zlib uncompress the failure. error code:" << err;
else
qDebug() << "zlib uncompress the success. data:" << uncompr;
2、zlib的compress压缩的数据调QT的qUncompress解压
只要在数据的前插入四个字节(数据长度),然后数据长度+4。
//qUncompress好像对前四位的原数据长度没要求,乱填都可以,只不过性能有些差距。
QByteArray zlibToQtUncompr(const char *pZLIBData, uLongf dataLen/*, uLongf srcDataLen = 0x100000*/)
{
char *pQtData = new char[dataLen + 4];
char *pByte = (char *)(&dataLen);/*(char *)(&srcDataLen);*/
pQtData[3] = *pByte;
pQtData[2] = *(pByte + 1);
pQtData[1] = *(pByte + 2);
pQtData[0] = *(pByte + 3);
memcpy(pQtData + 4, pZLIBData, dataLen);
QByteArray qByteArray(pQtData, dataLen + 4);
delete []pQtData;
return qUncompress(qByteArray);
}
QT环境测试:
char test2[] = "asdf451A21D54sadAS";
char compr[100];
int err = compress((Byte *)compr, &len, (const Bytef*)test2, strlen(test2));
if(err)
qDebug() << "zlib compress the failure. error code:" << err;
else
{
qDebug() << "zlib uncompress the success. data:" << zlibToQtUncompr(compr, 30);
}
就上面的数据,对zlibToQtUncompr调10000次,release模式下,如果前四位的原数据长度如果填1,执行时间在0.057-0.063秒之间。如果填前四位的原数据长度>=原数据长度,执行时间在0.005秒。可见效率差距多大,差了10倍。这效率差很有可能是差在分配内存,因为缓存空间过小后要重新分配,重复次数越多,效率就越慢。但如果前四位的原数据长度过大,qUncompress就会解压失败,很可能是要分配的空间过大。
目前验证过C/C++、JAVA的库都可以用。理论上应该是QT与所有语言的zlib库都能通过以上的方式执行压缩解压。