2016-09-19 60 views
0

我正在使用此函數進行zlib壓縮,並想知道outbuffer變量是否應設置爲特定大小?它是否將字符數組限制在這裏?我可以放在這裏的長度是否有限制?將它轉換爲std :: string是否有意義,因爲Im在C++中編譯?zlib C++壓縮緩衝區的字符大小

/** Compress a STL string using zlib with given compression level and return 
    * the binary data. */ 
    std::string compress_string(const std::string& str, int compressionlevel = 9) 
    { 
     z_stream zs;      // z_stream is zlib's control structure 
     memset(&zs, 0, sizeof(zs)); 

     if (deflateInit(&zs, compressionlevel) != Z_OK) 
      throw(std::runtime_error("deflateInit failed while compressing.")); 

     // For the compress 
     deflateInit2(&zs, compressionlevel, Z_DEFLATED,MOD_GZIP_ZLIB_WINDOWSIZE + 16,MOD_GZIP_ZLIB_CFACTOR,Z_DEFAULT_STRATEGY) != Z_OK; 

     zs.next_in = (Bytef*)str.data(); 
     zs.avail_in = str.size();   // set the z_stream's input 

     int ret; 
     char outbuffer[3222768]; 
     std::string outstring; 

     // retrieve the compressed bytes blockwise 
     do { 
      zs.next_out = reinterpret_cast<Bytef*>(outbuffer); 
      zs.avail_out = sizeof(outbuffer); 

      ret = deflate(&zs, Z_FINISH); 

      if (outstring.size() < zs.total_out) { 
       // append the block to the output string 
       outstring.append(outbuffer,zs.total_out - outstring.size()); 
      } 
     } 
     while (ret == Z_OK); 

     deflateEnd(&zs); 

     if (ret != Z_STREAM_END) {   // an error occurred that was not EOF 
      std::ostringstream oss; 
      oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; 
      throw(std::runtime_error(oss.str())); 
     } 

     return outstring; 
    } 
+1

Take aook [at this SO post](http://stackoverflow.com/questions/8902924/zlib-deflate-how-much-memory-to-allocate) – LPs

+0

如果你看看[zlib示例](http ://www.zlib.net/zlib_how.html)你會看到它使用的緩衝區大小隻有16k。 –

回答

0

這就是deflateBound()的用途。你的deflateInit2()後,你可以調用它的輸入大小,它會給你一個可能的擴展當壓縮不可壓縮的數據的約束。

順便說一句,在相同的結構上調用deflateInit/deflateInit2兩次會導致大的內存泄漏。請給他們打一次電話。您應該完整閱讀zlib documentation

+0

嗨,只是想知道你的意思是我應該從我的代碼中刪除deflateInit if語句? –

+0

您需要刪除'deflateInit()'或'deflateInit2()'。第二個永遠泄漏第一個分配的內存。順便說一下,第二個末尾的'!= Z_OK'是令人困惑的,因爲它什麼也不做。 –