使用开源的zip.cpp和unzip.cpp实现压缩包的创建与解压

news2024/11/17 20:27:06

目录

1、使用场景

2、压缩包的创建

3、压缩包的解压

4、CloseZipZ和CloseZipU两接口的区别 

5、开源zip.cpp和unzip.cpp文件的下载


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html       有时我们需要在代码中实现压缩包的创建以及对压缩包的解压,开源的win32版本的zip.cpp和unzip.cpp给我们提供了途径和办法,本文我们就来讲讲如何使用这两个开源的cpp文件实现压缩包的创建和解压。

1、使用场景

       压缩包的解压一般用在自制的安装包(自己实现的安装包程序,不使用InstallShield等打包工具)中。我们一般将要拷贝到安装路径下的文件打成zip包放置到安装包工程的资源中,集成到exe文件中,在执行安装包安装时,将zip压缩包从资源中取出来,解压到磁盘上,然后再将文件拷贝到安装路径中。

       开源的win32版本的zip.cpp与zip.h、unzip.cpp和unzip.h,出自:Zip Utils - C++/Win32。

2、压缩包的创建

      我们首先调用CreateZip接口创建一个压缩包,然后调用ZipAdd将文件添加到压缩包中。

       如果要将文件夹添加到压缩包中,则需要遍历文件夹中的文件,然后在调用ZipAdd时要把文件夹中的文件相对于压缩包的相对路径传递给ZipAdd。对文件夹的操作,我们已经封装成名叫AddZipFolder的接口。

       创建压缩包的代码如下所示,我们将config.ini文件和msssdk文件夹添加到压缩包中:

// 先创建zip包.zip文件,在把各个文件和文件夹添加进去,对于文件夹需要
// 递归遍历
HZIP hz = CreateZip( strUserZipFile, 0 );
if ( hz == NULL )
{
     return;
}

// 压缩包最上层的文件直接调用ZipAdd添加到压缩包中即可
CString strConfigFilePath = _T("D:\\config.ini");
if ( PathFileExists( strConfigFilePath ) )
{
    ZipAdd( hz, _T("login.ini"), strConfigFilePath );
}

// 如果是待压缩的中间包含文件夹,则在调用函数时,要自己维护文件的
// 层次关系,即加入的文件在当前zip包中应该是相对路径,所以调用
// AddZipFolder在传递绝对路径的同时,还要传递Users的相对路径
CString strZipDir = _T("D:\\msssdk");
if ( PathFileExists( strZipDir ) )
{
    AddZipFolder( hz, strZipDir, _T("msssdk") );
}

CloseZipZ( hz );

        处理文件夹的接口AddZipFolder实现如下:

void AddZipFolder( INS_ZIP::HZIP hz, LPCTSTR lpszDir, LPCTSTR lpRelPath )
{
	CString strFindFileName = lpszDir;
	strFindFileName += _T("\\*.*");  
	WIN32_FIND_DATA wfd;
	HANDLE hFindFile = FindFirstFile( strFindFileName, &wfd );
	if ( hFindFile == INVALID_HANDLE_VALUE )
	{
		return;
	}

	CString strFilePath;
	CString strRelPath;
	while ( 1 )      
	{                     
		if ( wfd.cFileName[0] != '.' )          
		{          
			strFilePath = lpszDir;
			strFilePath += _T("\\");
			strFilePath += wfd.cFileName;

			strRelPath = lpRelPath;
			strRelPath += _T("\\");
			strRelPath += wfd.cFileName;

			if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) // 目录
			{
				// 文件夹要递归调用
				AddZipFolder( hz, strFilePath, strRelPath );

				// 对于ZipAddFolder的调用,一般传入文加件名。如果文件夹中包含子文件夹,则要传入相对路径
				// 注意,不能不能传入绝对路径,因为ZipAddFolder会依次创建绝对路径中的文件。因为文件夹中
				// 包含子文件夹,比如msssdk\include,会先遍历到最上面的文件夹Users,
				// 在压缩包中线创建msssdk目录,当遍历到include,传入msssdk\include,由于父目录Users已经
				// 存在,所以只创建include目录

				// 相对路径,即加入的文件相对zip包的相对路径
				ZipAddFolder( hz, strRelPath );
			}
			else // 文件           
			{        
				// ZipAdd添加文件,要保证在压缩包中的相对位置,所以要传入相对路径strRelPath,最后一个参
				// 数则要传入待打包文件的完整路径
				ZipAdd( hz, (LPCTSTR)strRelPath, (LPCTSTR)strFilePath );
			}         
		} 

		if ( !FindNextFile( hFindFile, &wfd ) )
		{
			break;
		}
	}      

	FindClose( hFindFile );
}

3、压缩包的解压

      先调用OpenZip打开压缩包,然后调用GetZipItem获取压缩包中文件的个数,然后再for循环依次调用GetZipItem获取文件信息,依次调用UnzipItem将每个文件都解压出来,相关代码如下所示:

// 返回TRUE表示没有错误,返回FALSE表示有错误发生,
// strDstPath:解压出来的文件的存放路径,strZipName待解压的压缩包文件名(含绝对路径)
BOOL Unzip( CString strDstPath, CString strZipName )
{  
    BOOL bExistError = FALSE;
    SetCurrentDirectory( strDstPath );
    HZIP hz = OpenZip( strZipName, 0 );
    if ( hz == NULL )
    {
         return FALSE;
    }

    INS_UNZIP::ZIPENTRY ze;     
    INS_UNZIP::GetZipItem( hz, -1, &ze ); 
    int numitems = ze.index;
    for ( int i = 0; i < numitems; i++ )
    { 
        GetZipItem( hz, i, &ze );
        DWORD dwRet = INS_UNZIP::UnzipItem( hz, i, ze.name );

        // 解压有错误
        if ( dwRet != 0 )
        {
            CString strLog;
            strLog.Format( _T("[Unzip]文件解压错误:%s,  lasterror: 0x%08X"), ze.name, dwRet );
            WriteLog( strLog );
            bExistError = TRUE;
        }
    }

    CloseZipU( hz );  
    
    return !bExistError;
}

4、CloseZipZ和CloseZipU两接口的区别 

       在创建压缩包和解压压缩包之后,要记得调用关闭压缩包句柄的接口(CloseZipZ和CloseZipU两个接口),不然会有资源泄露。       

       这个地方要稍微区分一下CloseZipZ和CloseZipU两个接口,这两个接口咋一看上去很容易分不清。其实很简单,CloseZipZ接口的结尾Z对应zip首字母, CloseZipU接口的结尾U对应unzip首字母。 

       如果是调用CreateZip接口创建压缩包,将调用zip.cpp文件中的接口,关闭句柄时要使用对应的ClozeZipZ接口。

       如果是调用OpenZip接口打开压缩包进行解压,将调用unzip.cpp文件中的接口,关闭句柄时要使用对应的ClozeZipU接口。

5、开源zip.cpp和unzip.cpp文件的下载

       开源的zip.cpp和unzip.cpp及对应的头文件,可以到网盘中下载:

链接:https://pan.baidu.com/s/1yvFYkEs3Upxfqi2dmKVlQg 
提取码:p55w

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/492892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低代码平台组件间事件交互

事件的分类 我们主要依托于事件来进行组件间的交互。为了满足组件与组件、组件与系统、组件与服务端的交互&#xff0c;我们大致可以将事件分为三个类别&#xff1a; 组件方法&#xff1a;每个组件都会暴露出一些方法供其他组件进行调用。例如表格组件&#xff0c;我们可以暴…

Ubuntu18.04 设置 root 用户登录

Ubuntu18.04 设置 root 用户登录 1 设置 root 密码2 设置 root 登录 1 设置 root 密码 Ubuntu 安装后&#xff0c;root 用户默认是被锁定的&#xff0c;无法登录。Ubuntu 默认的 root 密码是动态随机的&#xff0c;我们的系统每次启动后都是不一样的&#xff0c;那么要使用 ro…

【滤波】多元高斯

本文主要翻译自rlabbe/Kalman-and-Bayesian-Filters-in-Python的第5章节05-Multivariate-Gaussians&#xff08;多元高斯&#xff09;。 %matplotlib inline#format the book import book_format book_format.set_style()简介 上一篇文章中的技术非常强大&#xff0c;但它们只…

[chapter 31][PyTorch][Early Stop Dropout]

前言 深度神经网络结构的过拟合是指 : 在训练集上的正确率很高, 但在测试集上的准确率很低. 为了缓解网络过拟合的问题, 其中一种常见的办法是使用 dropout ,Early Stop 目录&#xff1a; 1&#xff1a; Early Stop 2: Dropout 3: stochastic Gradient Descent 一 Earl…

平面设计师都在用的设计素材网站,免费下载~

很多新手设计师不知道去哪里找高清、免费的设计素材&#xff0c;今天我就给大家推荐5个设计素材网站&#xff0c;免费下载&#xff0c;赶紧收藏起来把&#xff01; 1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 菜鸟图库是我推荐过很多次的网站&#xff0c;主要是站内素…

白宫召见科技巨头 讨论AI潜在风险 以确保人们从创新中受益

ChatGPT的问世&#xff0c;被认为是通用人工智能发展的“奇点”和强人工智能即将到来的“拐点”&#xff0c;甚至有业内人士推测所有数字化系统和各个行业都可能被其重新“洗牌”。 乐观主义者表示&#xff0c;人工智能的核心是对人类大脑的模拟&#xff0c;其目的是延伸和增强…

C++Primer 第一章

C概述 程序的组成 数据的集合算法的集合 面向对象编程:我们通过一组数据抽象来建立问题的模型,简单来说就是把一些数据封装起来,就是我们类 面向过程编程:一个问题可直接由一组算法来建立模型 第一章 开始 1.1 问题的解决 这里有一个简单的例子来让我们看看如何设计编程思路…

C++ 的类型转换

目录 1. C语言中的类型转换 2. C强制类型转换 2.1static_cast 2.2 reinterpret_cast 2.3 const_cast 2.4 dynamic_cast 3. RTTI&#xff08;了解&#xff09; 1. C语言中的类型转换 在 C 语言中&#xff0c;如果 赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不…

华为OD机试真题-扑克牌大小【2023】【JAVA】

一、题目描述 扑克牌游戏大家应该都比较熟悉了&#xff0c;一副牌由54张组成&#xff0c;含3~A、2各4张&#xff0c;小王1张&#xff0c;大王1张。牌面从小到大用如下字符和字符串表示&#xff08;其中&#xff0c;小写joker表示小王&#xff0c;大写JOKER表示大王&#xff09…

【linux的学习】

文章目录 linux的学习一、工具安装与联网&#xff1f;二、Linux软件安装1.安装jdk2.安装MySQL2.读入数据 总结 linux的学习 一、工具安装与联网&#xff1f; 1.1安装好VM后 进入vi /etc/sysconfig/network-scripts/ifcfg-ens33 然后ip addr 查看ip 1.2打开IDEA的tools 二、…

Jpeg算法

Jpeg算法&#xff1a; JPEG会分析图片的各个部分找到并删除人眼不易察觉的元素。使用jpeg算法的时候可以选一个叫’质量’的可变数值来决定压缩的程度&#xff0c;压缩过多的时候我们会得到有缺陷的方框&#xff0c;叫做膺像。 压缩算法之所以有用的原因&#xff1a;人的眼睛并…

Linux开发工具大全 - 软件包管理器yum | vim编辑器 | gcc/g++编译器 | 自动化构建工具Make/Makefile | gdb调试工具

目录 Ⅰ. Linux 软件包管理器 yum 一、yum 背景知识 二、yum 的基本使用 1、查看软件包 2、软件包名称构成 3、安装软件 4、卸载软件 Ⅱ.vim编辑器 一、认识vim 1、vim概念 2、模式及其切换 二、vim使用 1、vim的指令&#xff08;重要&#xff09; 命令模式 插…

PCB表面处理方式详解

上一篇文章中介绍了关于PCB设计中的常用基本概念&#xff0c;那么本篇文章就挑选其中的第三点【表面处理】&#xff0c;给大家展开说一说&#xff0c;顺便也自我温习一下。 什么是表面处理&#xff1f; 由于铜长期与空气接触会使得铜氧化&#xff0c;所以我们需要在PCB表面做一…

【毕业设计】基于springboot的大学生综合素质测评管理系统

目录 前言介绍综合素质测评表特色功能页面展示一&#xff0e;开发环境1.JDK配置2.安装IDEA3.MySQL安装 二&#xff0e;项目导入和配置三&#xff0e;数据库配置1.创建数据库2.修改项目数据库配置 四&#xff0e;项目部署1.项目启动2.项目访问 在线体验其他类似系统关于我 前言 …

UDP协议介绍

文章目录 一、端口号二、UDP协议1.UDP协议格式2.UDP协议的特点3.UDP缓冲区 三、UDP注意事项 一、端口号 端口号是在网络中标识一台主机上进行通信程序的唯一性的&#xff0c;在TCP/IP协议中&#xff0c;用源IP、源端口号、目的IP、目的端口号、协议号这样一个五元组来标识一个…

Android Studio Flamingo | 2022.2.1 Patch 1(火烈鸟版本)

版本概况 Android Studio Flamingo | 2022.2.1 Patch 1 Build #AI-222.4459.24.2221.9971841, built on April 20, 2023 Runtime version: 17.0.60-b2043.56-9586694 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 10.0 GC: G1 Young Generation, G1 Old…

LLMs 记忆体全新升级:六大新功能全面出击,用户体验值拉满!

LLMs 时代之下&#xff0c;CVP Stack 必不可少。 其中&#xff0c;C 代表以 ChatGPT 为代表的大模型&#xff0c;它在 AI 程序中充当中央处理器的角色&#xff1b;V 代表 Vector Database&#xff0c;即以 Zilliz Cloud 和 Milvus 为代表的向量数据库&#xff0c;为大模型提供知…

3ds Max渲染慢怎么办_加快3ds Max渲染的一些技巧!

3ds Max是一款用于建筑可视化、产品建模、角色开发以及动画的3D建模软件。因此无论您是建筑师、产品设计师还是插画家&#xff0c;使用3ds Max制作项目都是您的绝佳软件选择。包括3ds Max在内的3D软件包通常都通过渲染过程&#xff0c;将3D模型转换为CGI。 项目在渲染后我们会看…

如何用ChatGPT做一门课?(包含大纲、脚本、PPT文本)

该场景对应的关键词库&#xff08;13个&#xff09;&#xff1a; 市场调研、在线网络课程、教学平台、社交媒体营销、子主题、细分领域、课程大纲、章节、推广渠道、课程脚本、文案基本要素、案例、具体方法 提问模板&#xff08;6个&#xff09;&#xff1a; 第一步&#xf…

C++实现一个异步日志库

C实现一个异步日志库 一、概念二、代码实现三、小结 一、概念 异步日志库&#xff08;Asynchronous Logging Library&#xff09;是一种用于记录应用程序运行时信息的库。相比于同步日志库&#xff0c;异步日志库能够提供更高的性能和可扩展性&#xff0c;因为它使用了异步写入…