2011-04-21 34 views
2

我使用Qt的zlib庫解壓從http服務器接收的gzip數據。因爲qUncompress是沒有好,我跟着這裏給出的建議是:Qt quncompress gzip data並創建了自己的方法來解壓縮gzip的數據,這樣的:使用Qt解壓縮gzip數據出錯

QByteArray gzipDecompress(QByteArray compressData) 
{ 
    //strip header 
    compressData.remove(0, 10); 

    const int buffer_size = 16384; 
    quint8 buffer[buffer_size]; 

    z_stream cmpr_stream; 
    cmpr_stream.next_in = (unsigned char *)compressData.data(); 
    cmpr_stream.avail_in = compressData.size(); 
    cmpr_stream.total_in = 0; 

    cmpr_stream.next_out = buffer; 
    cmpr_stream.avail_out = buffer_size; 
    cmpr_stream.total_out = 0; 

    cmpr_stream.zalloc = Z_NULL; 
    cmpr_stream.zfree = Z_NULL; 
    cmpr_stream.opaque = Z_NULL; 

    int status = inflateInit2(&cmpr_stream, -8); 
    if (status != Z_OK) { 
     qDebug() << "cmpr_stream error!"; 
    } 

    QByteArray uncompressed; 
    do { 
     cmpr_stream.next_out = buffer; 
     cmpr_stream.avail_out = buffer_size; 

     status = inflate(&cmpr_stream, Z_NO_FLUSH); 

     if (status == Z_OK || status == Z_STREAM_END) 
     { 
      QByteArray chunk = QByteArray::fromRawData((char *)buffer, buffer_size - cmpr_stream.avail_out); 
      uncompressed.append(chunk); 
     } 
     else 
     { 
      inflateEnd(&cmpr_stream); 
      break; 
     } 

     if (status == Z_STREAM_END) 
     { 
      inflateEnd(&cmpr_stream); 
      break; 
     } 
    } 
    while (cmpr_stream.avail_out == 0); 

    return uncompressed; 
} 

Eveything看來,如果解壓縮的數據適合輸出緩衝區做工精細(即小於16Kb)。如果不是,則第二次膨脹返回Z_DATA_ERROR。我知道數據是正確的,因爲如果輸出緩衝區足夠大,同一塊數據就可以正確地解壓縮。

服務器不與未壓縮的數據(只有一個壓縮的大小)的大小返回一個頭,所以我遵循的zlib的使用說明:http://www.zlib.net/zlib_how.html

而且他們這樣做,我到底是什麼這樣做。任何想法我可能會失蹤?流中的next_in和avail_in成員似乎在第一次迭代之後正確更新。噢,如果它有用,數據錯誤發出時的錯誤信息是:「無效距離太遠」。

有什麼想法?謝謝。

回答

3

Deflate/Inflate壓縮/解壓縮算法使用32Kb循環緩衝區。因此,如果解壓縮數據大於16Kb,16Kb緩衝區將無法工作。 (不完全是這樣,因爲數據可以被分割成塊,但是你需要假設那裏有32Kb的塊。)所以只需設置buffer_size = 32768,你應該沒問題。

+0

我有同樣的問題,我通過使用下面的方法解決這個問題試試這個 – pranavjayadev 2012-11-30 10:41:45