我想使用C++中的zlib来生成与gz兼容的输出文件。
我安装了zlib的开发人员包,据我所知,它可以在Unix和Windows上用于创建gz兼容文件。
虽然我编写了一个C++程序,但在相关点上,我相当遵循了使用示例。我还未更改地编译了示例中的
哎呀,我得到的输出结果并不与gz兼容。
根据我的理解,我遵循manual的指导来使用
通过这样打开文件:
此外,我想知道为什么我制作的
我安装了zlib的开发人员包,据我所知,它可以在Unix和Windows上用于创建gz兼容文件。
sudo aptitude install libz-dev
虽然我编写了一个C++程序,但在相关点上,我相当遵循了使用示例。我还未更改地编译了示例中的
zpipe.c
。哎呀,我得到的输出结果并不与gz兼容。
$ ./zpipe.x < data.txt > x.gz
$ file x.gz
x.gz: data
$ gunzip x.gz
gzip: x.gz: not in gzip format
我认为这里的原因可能是因为没有调用deflateSetHeader
。所以我将其添加到了我的源代码中,即(摘录,你可以在这里找到完整代码):
struct DeflateWrap { // RAII wrapper
z_stream strm_ ; // C-Struct from zlib.h
explicit DeflateWrap() : strm_{} {
strm_.zalloc = Z_NULL;
strm_.zfree = Z_NULL;
strm_.opaque = Z_NULL;
auto ret = deflateInit2(&strm_, LEVEL,
Z_DEFLATED, 15, 9, Z_DEFAULT_STRATEGY);
if(ret != Z_OK) throw std::runtime_error("Error ZLib-Init");
}
// ...more, eg. operator-> and *...
};
void pack(const string& infn) {
DeflateWrap dwrap {};
//...
dwrap->avail_in = indata.size();
dwrap->next_in = reinterpret_cast<unsigned char*>(indata.data());
gz_header header {0}; // <<< HEADER HERE
header.name = const_cast<unsigned char*>(
reinterpret_cast<const unsigned char*>(infn.c_str()));
header.comment = Z_NULL;
header.extra = Z_NULL;
bool first = true;
do {
dwrap->avail_out = outdata.size();
dwrap->next_out = reinterpret_cast<unsigned char*>(outdata.data());
if(first) {
cerr << deflateSetHeader(&(dwrap.strm_), &header); // <<< SET HDR HERE
first = false;
}
deflate(&(dwrap.strm_), Z_FINISH); // zlib.h: this packs
auto toWrite = outdata.size() - dwrap->avail_out;
outf.write(outdata.data(), toWrite);
} while (dwrap->avail_out == 0);
}
根据我的理解,我遵循manual的指导来使用
deflateSetHeader
:
- 我甚至使用了
deflateInit2
而不是deflateInit
,可能是不必要的 deflateSetHeader
的调用紧随deflateInit2
之后deflateSetHeader
的调用在任何deflate
的调用之前
...但仍然得到了-2
,即Z_STREAM_ERROR
的返回值。尽管如此,我生成的输出可以通过zpipe.c
进行解压缩,因此它不能完全错误,对吗?
有没有什么办法设置一个兼容gz的头文件呢?
更新:
据我所知,我使用了C++的等效函数。
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
通过这样打开文件:
ifstream inf{ infn, ifstream::binary };
ofstream outf { infn + ".gz", ofstream::binary };
此外,我想知道为什么我制作的
zpipe.c
示例也不能生成与gunzip兼容的文件,就像我之前描述的那样。根据我在这里阅读的内容,它应该可以。