c++ 为什么我使用zlib解压缩不正确?

zpqajqem  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(308)

请解释这是否是Zlib错误或我误解了Zlib的用法。
我正在努力做到以下几点:

  • 我有两个字符串-需要压缩的数据:string_data_1和string_data_2,我用Zlib将它们压缩为原始数据。
    接下来,我创建第三个字符串,并将已经压缩的数据复制到这一行中。
  • 现在,我正在解压缩此组合压缩数据,但出现了问题。
    Zlib只解压缩了压缩数据的“第一”部分,而没有解压缩第二部分。这是应该的吗?

例如facebook/zstd:Zstandard库中的-完全相同的操作-导致解压缩-所有压缩数据以及第一和第二部分。

下面是一个简单的代码:

#include <iostream>
#include <string>
#include <zlib.h>



int my_Zlib__compress__RAW(std::string& string_data_to_be_compressed, std::string& string_compressed_result, int level_compressed)
{

    //-------------------------------------------------------------------------
    uLong zlib_uLong = compressBound(string_data_to_be_compressed.size());         

    string_compressed_result.resize(zlib_uLong);
    //-------------------------------------------------------------------------

     //this is the standard Zlib compress2 function - with one exception: the deflateInit2 function is used instead of the deflateInit function and the windowBits parameter is set to "-15" so that Zlib compresses the data as raw data:
    int status = my_compress2((Bytef*)&string_compressed_result[0], &zlib_uLong, (const Bytef*)&string_data_to_be_compressed[0], string_data_to_be_compressed.size(), level_compressed);


    if (status == Z_OK)
    {
        string_compressed_result.resize(zlib_uLong);     

        return 0;
    }
        else
        { 
        return 1;
        }

}

int my_Zlib__uncompress__RAW(std::string& string_data_to_be_uncompressed, std::string& string_compressed_data, size_t size_uncompressed_data)
{

    //-------------------------------------------------------------------------
    string_data_to_be_uncompressed.resize(size_uncompressed_data);
    //-------------------------------------------------------------------------

    //this is the standard Zlib uncompress function - with one exception: the inflateInit2 function is used instead of the inflateInit function and the windowBits parameter is set to "-15" so that Zlib uncompresses the data as raw data:
    int status = my_uncompress((Bytef*)&string_data_to_be_uncompressed[0], (uLongf*)&size_uncompressed_data, (const Bytef*)&string_compressed_data[0], string_compressed_data.size());   

    if (status == Z_OK)
    {
        return 0;
    }
}



int main()
{

int level_compressed = 9;     

//------------------------------------------Compress_1-------------------------------------------
std::string string_data_1 = "Hello12_Hello12_Hello125";              //The data to be compressed.

std::string string_compressed_result_RAW_1;                             //Compressed data will be written here

int status = my_Zlib__compress__RAW(string_data_1 , string_compressed_result_RAW_1, level_compressed);
//----------------------------------------------------------------------------------------------

//--------------------------------------Compress_2----------------------------------------------
std::string string_data_2= "BUY22_BUY22_BUY223";              //The data to be compressed.

std::string string_compressed_result_RAW_2;                         //Compressed data will be written here

status = my_Zlib__compress__RAW(string_data_2 , string_compressed_result_RAW_2, level_compressed);
//----------------------------------------------------------------------------------------------

std::string Total_compressed_data = string_compressed_result_RAW_1 + string_compressed_result_RAW_2; //Combine two compressed data into one string

//Now I want to uncompress the data in a string - "Total_compressed_data"

//--------------------------------------Uncompress--------------------------------
std::string string_uncompressed_result_RAW;                         //Uncompressed data will be written here

int size_that_should_be_when_unpacking = string_data_1.size() + string_data_2.size();

status = my_Zlib__uncompress__RAW(string_uncompressed_result_RAW, Total_compressed_data, size_that_should_be_when_unpacking , level_compressed);
//--------------------------------------------------------------------------------

std::cout<<string_uncompressed_result_RAW<<std::endl;  //Hello12_Hello12_Hello125

}

Zlib只解压缩了压缩数据的“第一”部分,没有解压缩“第二”部分。
应该是这样吗?

8cdiaqws

8cdiaqws1#

正如注解中所指出的,一个zlib流的连接不是一个zlib流,你需要对第二个zlib流再次解压缩,或者首先把整个zlib流压缩成一个zlib流。
您需要使用uncompress2()的变体,而不是uncompress(),因为前者将在最后一个参数中返回第一个解压缩的zlib流的大小,这样您就知道从哪里开始解压缩第二个流。
更好的是,你应该使用inflate()函数来代替你的应用程序。保留未压缩的大小以用于解压缩意味着你在另一端需要它。你怎么得到它?你单独传输它吗?你不需要它。你应该使用inflate()来一次解压缩一个块,然后你不需要提前知道未压缩的大小。
你也应该使用deflate()函数来压缩,然后你可以保持流打开,并继续压缩直到你完成,然后你将有一个单一的zlib流。

相关问题