我是否可以在内存中读取zlib压缩文件而不将其实际提取到磁盘?如果你能提供一个片段就好了。
这是一个zLib inflate例程,它在内存中占用缓冲区并解压缩到提供的输出缓冲区中。这是一个“一次性”功能,因为它试图一次性膨胀整个输入缓冲区,并假设你已经给它足够的空间来适应它。还可以编写多镜头功能,根据需要动态增长目标缓冲区。
int inflate(const void *src, int srcLen, void *dst, int dstLen) {
z_stream strm = {0};
strm.total_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef *) src;
strm.next_out = (Bytef *) dst;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int err = -1;
int ret = -1;
err = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib
if (err == Z_OK) {
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) {
ret = strm.total_out;
}
else {
inflateEnd(&strm);
return err;
}
}
else {
inflateEnd(&strm);
return err;
}
inflateEnd(&strm);
return ret;
}
说明:
src:包含压缩(gzip或zlib)数据的源缓冲区 srcLen:源缓冲区的长度 dst:目标缓冲区,输出将写入其中 dstLen:目标缓冲区的长度
返回值:
Z_BUF_ERROR:如果dstLen不够大,无法适应膨胀的数据 Z_MEM_ERROR:如果没有足够的内存来执行解压缩 Z_DATA_ERROR:如果输入数据已损坏
否则,返回值是写入dst的字节数。
是的你可以; zlib通常用于嵌入式系统,将应用程序映像从ROM解压缩到RAM中 - 完全是内存到内存的操作。
zlib文档描述了必要的调用。
Raj Advani提供的解决方案不适用于多流zlib缓冲区。 gzip数据的解决方案:
void decompress(Bytef *src, int src_len, Bytef *dst, int dst_len)
{
z_stream strm = {0};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
while (src_len > 0)
{
strm.total_in = strm.avail_in = src_len;
strm.total_out = strm.avail_out = dst_len;
strm.next_in = src;
strm.next_out = (Bytef *) dst;
assert(inflateInit2(&strm, (MAX_WBITS + 16)) == Z_OK);
decompress_block(&strm, dst);
unsigned int processed = src_len - strm.avail_in;
src_len -= processed;
src += processed;
}
}
int decompress_block(z_stream *strm, void *dst)
{
int ret;
do
{
ret = inflate(strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_NEED_DICT && ret != Z_MEM_ERROR && ret != Z_DATA_ERROR);
assert(strm->avail_out > 0);
}
while (ret != Z_STREAM_END);
inflateEnd(strm);
assert(write(1, dst, strm->total_out) == strm->total_out);
return 0;
}