因爲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解壓
只要把qCompress壓縮的數據的前四位不要了,然後直接把後面的數據傳過去,然後數據長度-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庫都能通過以上的方式執行壓縮解壓。