windows c语言使用zlib库

zlib官网:zlib Home Site

zlib光网可以下载源码,也可以通过github下载源码:https://github.com/madler/zlib/tree/develop

下载后目录如下:

使用visual studio编译需要进入contrib\vstudio目录,里面有不同版本的vs解决方案,根据自己的visual studio版本选择即可:

编译库很简单,zlibvc.vcxprocj是库,编译产出文件是zlibwapi.lib和zlibwapi.dll,可以自己改成静态库版本。

使用库,有个小坑,自己编写了一个demo,库的确引入了,头文件只需要zlib.h和zconf.h两个文件,但是编译的时候,提示找不到uncompress和compress符号,对比zlib的demo【testzlibdll.vcxproj】发现工程里面定义了宏:ZLIB_WINAPI,自己的项目加上这个宏定义之后顺利编译通过。

简单demo

#include <stdio.h>

#include "include/zlib.h"

// 传入二进制数据的文件路径,没有字符串因为二进制数据不方便通过命令行传入
void testUnCompress(const char* filePath) {
	FILE* fp = NULL;
	int fileSize = 0;
	unsigned char* fileBuffer = NULL;
	unsigned char* outBuffer = NULL;
	uLongf outBufferSize = 0;
	int ret = 0;

	ret = fopen_s(&fp, filePath, "rb");
	if (!fp) {
		printf("fopen %s fialed, error:%d\r\n", filePath, ret);
		return;
	}

	fseek(fp, 0, SEEK_END);
	fileSize = ftell(fp);

	fseek(fp, 0, SEEK_SET);

	if (fileSize > 10 * 1024 * 1024) {
		printf("too big test file");
		return;
	}

	fileBuffer = new unsigned char[fileSize];

	if (!fileBuffer) {
		printf("new buffer failed for file:%d", fileSize);
		return;
	}

	ret = fread(fileBuffer, 1, fileSize, fp);
	if (ret != fileSize) {
		printf("read failed, %d!=%d", ret, fileSize);
		return;
	}

	printf("try uncompress:0x%02x 0x%02x ... 0x%02x 0x%02x \r\n",
		fileBuffer[0], fileBuffer[1], fileBuffer[fileSize-2], fileBuffer[fileSize-1]);

    // 以为不传入内存,接口会返回Z_MEM_ERROR结果并没有
    // 需要自己估计一个内存大小,根据zlib官方解释,压缩的负责人需要通过某个途径告诉解压缩的负责人,压缩之前数据量多大。
	outBuffer = new unsigned char[800];
	outBufferSize = 800;
	// 需要添加宏ZLIB_WINAPI否则提示找不到符号
	ret = uncompress(outBuffer, &outBufferSize, fileBuffer, fileSize);
	if (Z_MEM_ERROR == ret) {
		if (outBufferSize > 0) {
            // 并不会走到这个逻辑
			printf("need out buffer size:%lu\r\n", outBufferSize);
			if (outBufferSize > 100 * 1024 * 1024) {
				printf("buffer need too big, return\r\n");
				return;
			}
			outBuffer = new unsigned char[outBufferSize];

			ret = uncompress(outBuffer, &outBufferSize, fileBuffer, fileSize);
			if (Z_OK == ret) {
				printf("test uncompress success\r\n");
			}
			else {
				printf("test uncompress failed:%d\r\n", ret);
				return;
			}
		}
		else {
			printf("do not now how much buffer need\r\n");
			return;
		}
	}
	else {
		printf("first test uncompress return %d,outBufferSize=%d\r\n", ret, outBufferSize);
	}

	printf("test uncompress get data:\r\n%s\r\n", outBuffer);
}


// 压缩字符串,传入字符串,字符串有空格的话,命令行里面记得加双引号
void testCompress(const char* str) {
	int ret = 0;
	unsigned char* outBuffer = NULL;
	uLongf outSize = 0;


    // 可以通过compressBound获取压缩后大概多大,
	outBuffer = new unsigned char[60];
	outSize = 60;
	printf("try to comprss:%s\r\n", str);
	printf("len:%d\r\n", strlen(str));
    // compress是compress2的默认压缩级别
    // 此处传入的级别是9,可以使用其他级别。
	ret = compress2(outBuffer, &outSize, (const unsigned char*)str, strlen(str), 9);

	if (Z_MEM_ERROR == ret) {
		if (outSize > 0) {
            // 以为传入的目标大小不够时会走这个逻辑,其实并不会
			printf("need out buffer size:%lu\r\n", outSize);
			if (outSize > 1024) {
				printf("buffer need too big, return\r\n");
				return;
			}
			outBuffer = new unsigned char[outSize];

			ret = compress2(outBuffer, &outSize, (const unsigned char*)str, strlen(str), 9);
			if (Z_OK == ret) {
				printf("test uncompress success:\r\n%s\r\n", outBuffer);
			}
			else {
				printf("test uncompress failed:%d\r\n", ret);
				return;
			}
		}
		else {
			printf("do not now how much buffer need\r\n");
			return;
		}
	}
	else {
		printf("first test uncompress return %d\r\n", ret);
	}

    // 打印压缩后的二进制数据,只是测试而已,不要太认真
	for (int i = 0; i < outSize; ++i) {
		printf("0x%02x ", outBuffer[i]);
	}

	printf("\r\n");
}

坑:压缩代码不能提前知道数据被压缩后的大小,解压缩代码不能提前知道压缩前的大小。

解决方案:压缩前通过compressBound获取一个大概的压缩后的大小,解压缩的时候要求传入压缩前的大小。不然就只能通过代码一点点尝试了

Zlib是一种用于数据压缩和解压缩的开源,其提供的算法被广泛应用于各种应用程序中。在Windows平台上,我们可以使用zlib来进行数据压缩。 首先,我们需要安装zlib。可以从zlib的官方网站(http://www.zlib.net/)下载最新版本的zlib。下载后,解压缩文件并进入解压缩后的文件夹。 接下来,我们需要打开一个Windows命令提示符窗口。进入zlib的解压缩文件夹,在命令提示符窗口中进入该文件夹,执行以下命令: ``` nmake -f win32/Makefile.msc ``` 这将使用Microsoft Visual C++编译器构建zlib的静态版本。 编译完成后,在zlib的解压缩文件夹中可以找到生成的zlib静态文件(.lib)和头文件(.h)。 现在,打开Visual Studio或其他支持C语言开发的IDE,创建一个新的C语言项目。将zlib的头文件(.h)复制到项目中,并在项目设置中添加zlib的静态文件(.lib)。 现在,我们可以在项目中使用zlib进行数据压缩。需要包含zlib的头文件,并使用zlib提供的函数进行数据压缩和解压缩。 以下是一个使用zlib进行数据压缩的示例: ```c #include <stdio.h> #include <zlib.h> #define CHUNK 16384 int main() { FILE *sourceFile = fopen("source.txt", "rb"); FILE *compressedFile = fopen("compressed.zlib", "wb"); unsigned char in[CHUNK]; unsigned char out[CHUNK]; z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; deflateInit(&stream, Z_DEFAULT_COMPRESSION); int bytesRead, bytesWritten; do { bytesRead = fread(in, 1, CHUNK, sourceFile); stream.avail_in = bytesRead; stream.next_in = in; do { stream.avail_out = CHUNK; stream.next_out = out; deflate(&stream, Z_FINISH); bytesWritten = CHUNK - stream.avail_out; fwrite(out, 1, bytesWritten, compressedFile); } while (stream.avail_out == 0); } while (bytesRead > 0); deflateEnd(&stream); fclose(sourceFile); fclose(compressedFile); return 0; } ``` 上述示例中,我们打开了一个源文件(source.txt)用于数据压缩,并创建了一个压缩后的文件(compressed.zlib)。通过循环读取源文件的数据块并使用deflate函数进行压缩,将压缩后的数据块写入压缩后的文件中。最后,我们使用deflateEnd函数结束压缩过程。 通过这样的方式,我们可以使用zlibWindows平台上进行数据压缩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值