QT(qCompress和qUncompress)與zlib(compress和uncompress)相互調用

因爲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庫都能通過以上的方式執行壓縮解壓。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章