2

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

这是我尝试读取文件的尝试。我预计不会工作,因为 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 存档文件是否有条目?

4

2 回答 2

1

一种可能的替代方法是使用boost::iostreams带有内置 gzip 过滤器的库,它可以完全满足您的需求 - 从内存中的 gzip 文件进行流式解压缩。这是对gzip 过滤器的引用,以及来自相同的片段:

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

于 2019-01-21T09:13:16.510 回答
0

有两种方法可以使用zlib

  1. 使用内置的 GzFile API:Coliru Link - 在此处阅读更多信息
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. 原生inflateAPI:Coliru Link更多关于这在上面和这里的手动链接。我的代码几乎完全是提供的链接的副本,而且很长,所以我不会重新发布。
于 2019-03-14T22:35:51.003 回答