zlib库编译过程遇到的问题及其使用zlib库进行解压缩

本文详细介绍了如何在VS2008环境下编译zlib1.2.7库,包括下载zlib源码、编译过程以及解决64位系统编译问题。同时,还讲解了使用编译好的zlib库进行文件解压的准备工作,如添加库文件、复制dll到系统目录,并提供了解压文件的关键代码步骤。

目录

1. 下载zlib

2. 编译zlib

3. 使用zlib库解压文件

    3.1 准备工作

    3.2 使用解压函数对文件进行解压


1. 下载zlib

可以去官网http://www.zlib.net/ 下载zlib

2. 编译zlib

ps:此处运行环境为VS2008+zlib1.2.7

step1:打开VS2008的命令行运行窗口

step2:打开命令行窗口后,进入zlib-1.2.7\contrib\masmx86目录,输入bld_ml32.bat命令,按下回车键运行该命令

出现上述消息说明编译成功。

PS:由于现在机器基本都是64位,所以一般都是进入masmx64目录,执行bld_ml64.bat。但由于我在Win7和Win10系统环境下执行时出现“ml64.exe不是内部或外部命令,也不是可运行的程序”错误,错误如下图所示,由于操作系统内部会自动将32位软件地址向64位地址对齐,因此在64位机器上使用32位软件没问题!综上,我们这里编译bld_ml32.bat~

step3:进入目录D:\zlib-1.2.7\contrib\vstudio\vc9,由于我使用的是vs2008运行,所以进入的是vc9目录。接着用vs2008打开zlibvc.sln

step4:vs2008打开该文件后,首先要将该项目属性的预处理器设置为win32,然后编译该项目(按一下F5~)

step5:此时D:\zlib-1.2.7\contrib\vstudio\vc9\x86目录下就出现了一个ZlibDllDebug文件夹,装有编译好的dll库和lib

以上zlib库编译完成~


3. 使用zlib库解压文件

3.1 准备工作

要在项目中使用zlib库解压文件,需要先做一些准备工作~在要使用zlib库的项目文件中新建一个文件夹,这里我命名为zlib,里面的文件有:(由于这里只是使用zlib库解压,所以包含以下文件足以够用)

此时还需要将zlibwapi.dll放到windows/System中,不然运行时会报错~

最后只需在项目代码中加入这两行代码即可~

    #include "zlib/unzip.h"
    #pragma comment(lib, "zlib/zlibwapi.lib") 

以上准备工作完成,接下来可以在代码中使用zlib库的函数对文件进行解压啦~ 

3.2 使用解压函数对文件进行解压

1)打开压缩文件。利用unzOpen64(char* filePath)函数打开压缩文件,其返回值若为NULL则说明打开压缩文件失败;否则返回打开unzFile类型的变量说明成功打开压缩文件。

2)获取压缩文件的全局消息。利用unzGetGlobalInfo64(unzFile zFile, unz_global_info64 *zGlobalInfo)函数获取压缩文件的全局消息,放到unz_global_info64结构体中,其中有个重要的成员变量——压缩文件内所有文件的数量,但不包括目录。因此可以利用该函数得知压缩文件内的文件数量。

3)循环遍历压缩文件内的所有文件,并将压缩文件解压到本地文件中(其实这就是将读取到的文件写到本地文件中,从而完成解压)。

    	//遍历所有文件
        unz_file_info64 zFileInfo;
	unsigned int num = 512;
	char *fileName = new char[num];
	char *fileData = new char[500*1024];

        // zGlobalInfo.number_entry就是获取压缩文件的所有文件数量
	for(int i=0; i < zGlobalInfo.number_entry; i++)
	{
		// 获得压缩文件里的文件(下称为当前压缩文件)信息(其中fileName是全路径名)
		if(UNZ_OK != unzGetCurrentFileInfo64(zFile,&zFileInfo,fileName,num,NULL,0,NULL,0))
		{
			cout<<"得到当前文件信息出错"<<endl;
			return ;
		}
                // 打开当前压缩文件
		if(UNZ_OK != unzOpenCurrentFile(zFile))
		{
			cout<<"打开压缩包中"<<fileName<<"文件失败"<<endl;
			return ;
		}
                // 压缩文件全局信息结构体中的成员变量——未解压前文件的大小
		int fileLength = zFileInfo.uncompressed_size;
		
		//解压缩文件
                // 读取当前压缩文件,返回值为读取的字节长
                int len;
		len = unzReadCurrentFile(zFile,(voidp)fileData,fileLength);
		fileData[len] = '\0';

		//写入到本地解压缩后的文件中 
                // 由于ofstream不能创建带/的文件名,而fileName是绝对路径,包括/,因此要先对fileName字符串分割,获得最后一个/后面的文件名,这才是我们所需要的解压后文件名
		std::string strFileName = fileName;
		int nLength = strFileName.length();
		int nPos ;
		nPos = strFileName.find_last_of("/", nLength);
		std::string strPath = strFileName.substr(nPos+1, nLength);
		std::ofstream file(strPath.c_str(),std::ios::out|std::ios::binary);

		if(!file.good())
		{
			cout<<"file not good"<<endl;
			return ;
		}
                // 将指针定位到文件的一开始
		file.seekp(0,std::ios::beg);
		file.write(fileData,len);
		file.close();
                // 关闭当前解压文件
		unzCloseCurrentFile(zFile);
                // 下一个解压文件
		unzGoToNextFile(zFile);
	}
	unzClose(zFile);
	delete[] fileData;

完整解压代码如下:

void unzip(LPCTSTR szSavePath)
{
	unzFile zFile;
	// Unicode转为ANSI
	char filePath[MAX_PATH];
	WideCharToMultiByte(CP_ACP, 0, szSavePath, -1, filePath, MAX_PATH, NULL, NULL);
	// 打开压缩文件
	zFile = unzOpen64(filePath);
	if (zFile == NULL)
	{
		//MessageBox(L"打开压缩文件失败");
		return;
	}

	// 获取压缩文件的全局消息
	unz_global_info64 zGlobalInfo; 
	// 重要成员变量是压缩文件内所有文件的数量(不包括目录)
	if (UNZ_OK != unzGetGlobalInfo64(zFile, &zGlobalInfo))
	{
		//OutputDebugString(__FILE__ + L"中"+__LINE__+L"行错误,得到全局信息出错");
		return;
	}

	// 循环遍历所有文件
	unz_file_info64 zFileInfo;
	unsigned int num = 512;
	char *fileName = new char[num];
	char *fileData = new char[500*1024];

	for(int i=0; i < zGlobalInfo.number_entry; i++)
	{
		//遍历所有文件(fileName是全路径名)
		if(UNZ_OK != unzGetCurrentFileInfo64(zFile,&zFileInfo,fileName,num,NULL,0,NULL,0))
		{
			//cout<<"得到当前文件信息出错"<<endl;
			return ;
		}
		if(UNZ_OK != unzOpenCurrentFile(zFile))
		{
			//cout<<"打开压缩包中"<<fileName<<"文件失败"<<endl;
			return ;
		}
		int fileLength = zFileInfo.uncompressed_size;
		int len;
		//解压缩文件
		len = unzReadCurrentFile(zFile,(voidp)fileData,fileLength);
		fileData[len] = '\0';
		//写入到解压缩后的文件中 
		std::string strFileName = fileName;
		int nLength = strFileName.length();
		int nPos ;
		nPos = strFileName.find_last_of("/", nLength);
		std::string strPath = strFileName.substr(nPos+1, nLength);
		std::ofstream file(strPath.c_str(),std::ios::out|std::ios::binary);

		if(!file.good())
		{
			//cout<<"file not good"<<endl;
			return ;
		}
		file.seekp(0,std::ios::beg);
		file.write(fileData,len);
		file.close();
		unzCloseCurrentFile(zFile);
		unzGoToNextFile(zFile);
	}
	unzClose(zFile);
	delete[] fileData;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值