【问题标题】:Using zlib1.2.7 uncompress gzip data,how to get the files' name in the compression package使用zlib1.2.7解压gzip数据,如何获取压缩包中的文件名
【发布时间】:2016-01-25 09:04:31
【问题描述】:

使用zlib 1.2.7版本解压gzip数据,但我不知道如何获取压缩包中的文件名,或者你正在提取的文件名。我找到的方法,它看起来像读取所有数据到缓冲区,然后返回它。

像这样:

int gzdecompress(Byte *zdata, uLong nzdata, Byte *data, uLong *ndata)
{
    int err = 0;
    z_stream d_stream = {0}; /* decompression stream */
    static char dummy_head[2] = {
        0x8 + 0x7 * 0x10,
        (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
    };
    d_stream.zalloc = NULL;
    d_stream.zfree = NULL;
    d_stream.opaque = NULL;
    d_stream.next_in  = zdata;
    d_stream.avail_in = 0;
    d_stream.next_out = data;
    //only set value "MAX_WBITS + 16" could be Uncompress file that have header or trailer text
    if(inflateInit2(&d_stream, MAX_WBITS + 16) != Z_OK) return -1;
    while(d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
        if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
        if(err != Z_OK) {
            if(err == Z_DATA_ERROR) {
                d_stream.next_in = (Bytef*) dummy_head;
                d_stream.avail_in = sizeof(dummy_head);
                if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK) {
                    return -1;
                }
            } else return -1;
        }
    }
    if(inflateEnd(&d_stream) != Z_OK) return -1;
    *ndata = d_stream.total_out;
    return 0;
}

使用示例:

// file you want to extract
filename = "D:\\gzfile";

// read file to buffer
ifstream infile(filename, ios::binary);
if(!infile)
{
    cerr<<"open error!"<<endl;
}
int begin = infile.tellg();
int end = begin;
int FileSize = 0;
infile.seekg(0,ios_base::end);
end = infile.tellg();
FileSize = end - begin;

char* buffer_bin = new char[FileSize];
char buffer_bin2 = new char[FileSize * 2];

infile.seekg(0,ios_base::beg);
for(int i=0;i<FileSize;i++)
    infile.read(&buffer_bin[i],sizeof(buffer_bin[i]));
infile.close( );

// uncompress 
uLong ts = (FileSize * 2);
gzdecompress((Byte*)buffer_bin, FileSize, (Byte*)buffer_bin2, &ts);

数组“buffer_bin2”获取提取的数据。属性“ts”为数据长度。

问题是,我不知道它叫什么,只有一个文件。我怎样才能得到信息?

【问题讨论】:

    标签: c++ c gzip zlib


    【解决方案1】:

    您的问题完全不清楚,但是如果您尝试获取存储在 gzip 标头中的文件名,那么您应该阅读zlib.h 中的 zlib 文档。事实上,如果您打算以任何身份使用 zlib,那将是个好主意。

    在文档中,您会发现inflate...() 函数将解压缩gzip 数据,并且有一个inflateGetHeader() 函数将返回gzip 标头内容。

    请注意,当gzip 解压缩.gz 文件时,它甚至不会查看标题中的名称,除非明确要求。 gzip 将解压为.gz 文件的名称,例如foo.gz 解压后变为 foo,即使 gzip 标头显示名称为 bar。如果您使用gzip -dN foo.gz,那么它将调用它bar。不清楚为什么你甚至关心 gzip 标头中的名称是什么。

    【讨论】:

    • 例如:“A”是一个.gz文件。里面有两个.txt文件,分别叫“ua.txt”、“ub.txt”。我用gzip的方法解压数据,希望将它们保存到“ua.txt”、“ub.txt”。我写的函数,数组“buffer_bin2”只是数据,我需要知道我将创建哪个文件。我在文档中看到了函数 inflateGetHeader(),但我不知道如何使用它来获取文件名。你能请告诉我?
    • 不,你不能有两个文件。 gzip 文件只存储一个文件且仅存储一个文件。您指的是.tar.gz 文件吗?
    • 好尴尬。呃...文件是用C#“GZipStream”存储的。我开发了C++代码来解压数据。所以只有一个文件...Okey非常非常感谢,和你能告诉我如何使用函数 inflateGetHeader() 吗?我仍然需要知道原始文件名。
    • 阅读 zlib 文档了解如何使用其功能。
    猜你喜欢
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多