见示例:
其中调用inflate()后,zlib会保存解压进程,avail_in,next_in会更新,保存解压进程的断点。avail_out == 0说明这次输出内存用完,数据可能还没解压完,需要继续调用inflate(), 会从上次的位置继续解压。
#include <stdio.h>
/* For "exit". */
#include <stdlib.h>
/* For "strerror". */
#include <string.h>
/* For "errno". */
#include <errno.h>
#include <zlib.h>
/* CHUNK is the size of the memory chunk used by the zlib routines. */
#define CHUNK 0x4000
/* The following macro calls a zlib routine and checks the return
value. If the return value ("status") is not OK, it prints an error
message and exits the program. Zlib's error statuses are all less
than zero. */
#define CALL_ZLIB( x ) \
{ \
int status; \
status = x; \
if( status < 0 ) \
{ \
fprintf( stderr, \
"%s:%d: %s returned a bad status of %d.\n", \
__FILE__, \
__LINE__, \
#x, \
status ); \
exit( EXIT_FAILURE ); \
} \
}
/* if "test" is true, print an error message and halt execution. */
#define FAIL( test, message ) \
{ \
if( test ) \
{ \
inflateEnd( &strm ); \
fprintf( stderr, \
"%s:%d: " message " file '%s' failed: %s\n", \
__FILE__, \
__LINE__, \
file_name, \
strerror( errno ) ); \
exit( EXIT_FAILURE ); \
} \
}
/* These are parameters to inflateInit2. See
http://zlib.net/manual.html for the exact meanings. */
#define windowBits 15
#define ENABLE_ZLIB_GZIP 32
int main()
{
const char* file_name = "test.gz";
FILE* file;
z_stream strm = {0};
unsigned char in[CHUNK];
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.next_in = in;
strm.avail_in = 0;
CALL_ZLIB( inflateInit2( &strm, windowBits | ENABLE_ZLIB_GZIP ) );
/* Open the file. */
file = fopen( file_name, "rb" );
FAIL( !file, "open" );
while( 1 )
{
int bytes_read;
int zlib_status;
bytes_read = fread( in, sizeof( char ), sizeof( in ), file );
FAIL( ferror( file ), "read" );
strm.avail_in = bytes_read;
strm.next_in = in;
do
{
unsigned have;
strm.avail_out = CHUNK;
strm.next_out = out;
zlib_status = inflate( &strm, Z_NO_FLUSH );
switch( zlib_status )
{
case Z_OK:
case Z_STREAM_END:
case Z_BUF_ERROR:
break;
default:
inflateEnd( &strm );
fprintf( stderr, "Gzip error %d in '%s'.\n", zlib_status, file_name );
return -1;
}
have = CHUNK - strm.avail_out;
fwrite( out, sizeof( unsigned char ), have, stdout );
} while( strm.avail_out == 0 );
if( feof( file ) )
{
inflateEnd( &strm );
break;
}
}
FAIL( fclose( file ), "close" );
return 0;
}
本文介绍了一个使用Zlib库解压缩GZIP格式文件的C语言程序示例。程序通过读取GZIP文件,调用inflate()函数进行解压缩,并将解压缩后的数据输出到标准输出。文章详细解释了inflate()函数的工作原理,包括如何处理解压过程中的状态更新和内存分配。

4880

被折叠的 条评论
为什么被折叠?



