使用zlib实现gzip压缩

读写文件 

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>

int main()
{
    int err;
    int len = 11;
    gzFile file;
    z_off_t pos;
    unsigned char uncompr[128] = {0};
    int uncomprLen = 128;
    file = gzopen("testgzip.gz", "wb");
    if (file == NULL)
    {
        fprintf(stderr, "gzopen error\n");
        return -1;
    }
    gzputc(file, 'h');
    if (gzputs(file, "ello") != 4)
    {
        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
        return -1;
    }
    if (gzprintf(file, ", %s!", "hello") != 8)
    {
        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
        return -1;
    }
    gzseek(file, 1L, SEEK_CUR);
    gzclose(file);

    file = gzopen("testgzip.gz", "rb");
    if (file == NULL)
    {
        fprintf(stderr, "gzopen error\n");
        return -1;
    }
    len = gzread(file, uncompr, (unsigned)uncomprLen);
    printf("gzread len: %d\n", len);
    printf("(char *)uncompr = %s\n", (char *)uncompr);
    pos = gzseek(file, -8L, SEEK_CUR);
    if (pos != 6 || gztell(file) != pos)
    {
        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
                (long)pos, (long)gztell(file));
        return -1;
    }

    if (gzgetc(file) != ' ')
    {
        fprintf(stderr, "gzgetc error\n");
        return -1;
    }

    if (gzungetc(' ', file) != ' ')
    {
        fprintf(stderr, "gzungetc error\n");
        return -1;
    }

    gzgets(file, (char *)uncompr, (int)uncomprLen);
    if (strlen((char *)uncompr) != 7)
    { /* " hello!" */
        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
        return -1;
    }
    gzclose(file);
}

内存压缩

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <zlib.h>


int compress(const char *src, int srcLen, char *dst, int dstLen)
{
	z_stream strm;
	//初始化strm结构中的zalloc, zfree, opaque,要求使用默认的内存分配策略
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;

	//设置输入输出缓冲区
	strm.avail_in = srcLen;
	strm.avail_out = dstLen;
	strm.next_in = (Bytef *)src;
	strm.next_out = (Bytef *)dst;

	int err = -1;
	//初始化zlib的状态,成功返回Z_OK
	//deflateInit:zlib格式,deflateInit2:gzip格式
	//     err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
	err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
	if (err == Z_OK)
	{
		//Z_FINISH表明完成输入,让deflate()完成输出
		err = deflate(&strm, Z_FINISH);
		//Z_STREAM_END表明所有的输入都已经读完,所有的输出也都产生
		if (err == Z_STREAM_END)
		{
			//deflateEnd释放资源,防止内存泄漏
			(void)deflateEnd(&strm);
			 printf("compression succed, before compression size is %d, after compressione size is %d\n" ,strm.total_in ,dstLen - strm.avail_out);
			//strm.avail_out表明输出缓冲区剩余的空闲空间大小
			return dstLen - strm.avail_out;
		}
		else
		{
			(void)deflateEnd(&strm);
			printf("compression failed, deflate return: !\n");
			return -1;
		}
	}
	else
	{
		(void)deflateEnd(&strm);
		printf("compression initialization failed, quit!\n");
		return 0;
	}
}

int decompress(const char *src, int srcLen, char *dst, int dstLen)
{
	z_stream strm;
	strm.zalloc = NULL;
	strm.zfree = NULL;
	strm.opaque = NULL;

	strm.avail_in = srcLen;
	strm.avail_out = dstLen;
	strm.next_in = (Bytef *)src;
	strm.next_out = (Bytef *)dst;

	int err = -1;
	err = inflateInit2(&strm, MAX_WBITS + 16);
	//err = inflateInit(&strm);
	if (err == Z_OK)
	{
		err = inflate(&strm, Z_FINISH);
		if (err == Z_STREAM_END)
		{
			(void)inflateEnd(&strm);
			printf("decompress succed, before decompress size is %d, after decompress size is %d\n", strm.total_in, dstLen - strm.avail_out);
			return strm.total_out;
		}
		else
		{
			(void)inflateEnd(&strm);
			printf("decompression failed, inflate return: \n");
			return -1;
		}
	}
	else
	{
		inflateEnd(&strm);
		printf("decompression initialization failed, quit!\n");
		return 0;
	}
}

int main(int argc, char const *argv[])
{
	char* str = "hello, hello";
	int len = strlen(str);
	int res = -1;
	char buf[65536];
	char buf_[65536];
	int fd = open("testgzip.gz", O_RDONLY);
	if(fd < 0)
	{
		return -1;
	}

	res = read(fd, buf, 1024);
	close(fd);
	printf("read = %d\n", res);
	for (int i = 0; i < res; i++)
	{
		printf("%02x", buf[i]);
	}
	printf("\n");

	res = decompress(buf, res, buf_, sizeof(buf_));
	buf_[res] = 0;
	printf("decompress: %s\n", buf_ );

	res = compress(str, len, buf, sizeof(buf));
	for (int i = 0; i < res; i++)
	{
		printf("%02x", buf[i]);
	}
	printf("\n");
	res = decompress(buf, res, buf_, sizeof(buf_));
	buf_[res] = 0;
	printf("decompress: %s\n", buf_);
	return 0;
}

编译命令要加 -lz

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值