[英]Decompressing gzip file to memory using libarchive
I'm trying to decompress programmatically a gzip file into memory and mimic the command gzip -d file.gz
using libarchive project .我正在尝试以编程方式将 gzip 文件解压缩到内存中,并使用libarchive project模拟命令
gzip -d file.gz
。 The file is actually taken from http response with the following header Accept-Encoding: gzip, deflate
该文件实际上取自带有以下标头
Accept-Encoding: gzip, deflate
http 响应
Here my attempt to read the file.在这里,我尝试读取文件。 I don't expect not to work since the gzipped file has no entries (it's compressed as a stream) and
archive_read_next_header
tries to read the next file out of the arcihve.我不希望它不起作用,因为 gzipped 文件没有条目(它被压缩为流)并且
archive_read_next_header
尝试从存档中读取下一个文件。
Are there any alternative to this function that extract the entire data out of the compressed file.是否有任何替代此功能的方法可以从压缩文件中提取整个数据。
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);
Perhaps someone can post minimal code example that resolve this issue ?也许有人可以发布解决此问题的最小代码示例? Also, Is there an option to find out whether a gzip archive file has entries or not ?
另外,是否可以选择查看 gzip 存档文件是否有条目?
One possible alternative is to use boost::iostreams
library which comes with an inbuilt gzip filter and allows exactly what you want - streaming decompression from a gzip file in memory.一种可能的替代方法是使用
boost::iostreams
库,该库带有内置的 gzip 过滤器,并允许您完全按照您的要求进行操作——从内存中的 gzip 文件流式解压。 Here is the reference to the gzip filter , and a snippet from the same:这是对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);
Edit: Actually a much better snippet is available here https://stackoverflow.com/a/16693807/3656081编辑:实际上这里有一个更好的片段https://stackoverflow.com/a/16693807/3656081
There are two ways to do this using zlib
:使用
zlib
有两种方法可以做到这一点:
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;
}
inflate
API: Coliru Link .inflate
API: Coliru Link 。 More on this in the manual link above and here .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.