使用libarchive将gzip文件解压缩到内存

时间:2019-01-21 08:18:44

标签: c++ c gzip deflate libarchive

我正在尝试以编程方式将gzip文件解压缩到内存中,并使用libarchive project模拟命令gzip -d file.gz。 该文件实际上是从带有以下标头Accept-Encoding: gzip, deflate

的http响应中获取的

在这里,我尝试读取文件。我不希望它不起作用,因为gzip压缩的文件没有任何条目(它被压缩为流),并且archive_read_next_header试图从目录中读取下一个文件。

此功能是否有其他选择可从压缩文件中提取全部数据。

archive_read_support_format_raw(archive); 
archive_read_support_filter_all(archive);
archive_read_support_compression_all(archive)

archive_read_open_memory(archive, file_data, file_size);
struct archive_entry *entry;
la_ssize_t total, size;
char *buf;    
int status = archive_read_next_header(archive, &entry);

也许有人可以发布最少的代码示例来解决此问题? 另外,是否可以选择查找gzip存档文件中是否包含条目?

2 个答案:

答案 0 :(得分:1)

一种可能的替代方法是使用boost::iostreams库,该库带有内置的gzip过滤器,并且可以完全满足您的需要-从内存中的gzip文件中进行流式解压缩。这是对gzip filter的引用,以及其中的摘录:

ifstream file("hello.gz", ios_base::in | ios_base::binary);
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(file);
boost::iostreams::copy(in, cout);

编辑:实际上,这里https://stackoverflow.com/a/16693807/3656081

有一个更好的摘录

答案 1 :(得分:0)

有两种方法可以使用zlib

  1. 使用内置的GzFile API:Coliru Link-有关此here的更多信息
int inf(FILE* fp) {
    auto gzf = ::gzdopen(fileno(fp), "r");
    assert(::gztell(gzf) == 0);
    std::cout << "pos: " << ::gztell(gzf) << std::endl;
    ::gzseek(gzf, 18L, SEEK_SET);
    char buf[768] = {0};
    ::gzread(gzf, buf, sizeof(buf)); // use a custom size as needed
    std::cout << buf << std::endl; // Print file contents from 18th char onward
    ::gzclose(gzf);
    return 0;
}
  1. 本机inflate API:Coliru Link。上面和here的手动链接中对此有更多介绍。我的代码几乎完全是所提供链接的重复,并且相当长,因此我不会重新发布。