c++将文件夹或者文件打包成zip是需要用到第三方库,本博文假设读者都已安装了zlib库了,这里就直接使用了。如果读者没有安装好,可以参考我的上一篇博文

vs2015零基础编译zlib从失败到成功

1、配置目录

zlib文件夹是这样子
在这里插入图片描述
项目的目录

在这里插入图片描述
其中bin目录是输出目录,可以这样设置
在这里插入图片描述
然后配置包含目录与库目录,其中库目录需要自己在zlib里创建lib,把图片里两个加载进去
在这里插入图片描述

在这里插入图片描述

2、源码

#define ZLIB_WINAPI
#include <string>
#include <iostream>
#include <vector>
#include <Shlwapi.h> 
#include <zip.h>
#include <unzip.h>
#include <zlib.h>

using namespace std;

#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "zlibstat.lib")

bool nyAddfiletoZip(zipFile zfile, const std::string& fileNameinZip, const std::string& srcfile)
{
	// 目录如果为空则直接返回
	if (NULL == zfile || fileNameinZip.empty())
	{
		return 0;
	}

	int nErr = 0;
	zip_fileinfo zinfo = { 0 };
	tm_zip tmz = { 0 };
	zinfo.tmz_date = tmz;
	zinfo.dosDate = 0;
	zinfo.internal_fa = 0;
	zinfo.external_fa = 0;

	char sznewfileName[MAX_PATH] = { 0 };
	memset(sznewfileName, 0x00, sizeof(sznewfileName));
	strcat_s(sznewfileName, fileNameinZip.c_str());
	if (srcfile.empty())
	{
		strcat_s(sznewfileName, "\\");
	}

	nErr = zipOpenNewFileInZip(zfile, sznewfileName, &zinfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
	if (nErr != ZIP_OK)
	{
		return false;
	}
	if (!srcfile.empty())
	{
		// 打开源文件
		FILE* srcfp = _fsopen(srcfile.c_str(), "rb", _SH_DENYNO);
		if (NULL == srcfp)
		{
			std::cout << "打开源文件失败" << std::endl;
			return false;
		}

		// 读入源文件写入zip文件
		int numBytes = 0;
		char* pBuf = new char[1024 * 100];
		if (NULL == pBuf)
		{
			std::cout << "新建缓冲区失败" << std::endl;
			return 0;
		}
		while (!feof(srcfp))
		{
			memset(pBuf, 0x00, sizeof(pBuf));
			numBytes = fread(pBuf, 1, sizeof(pBuf), srcfp);
			nErr = zipWriteInFileInZip(zfile, pBuf, numBytes);
			if (ferror(srcfp))
			{
				break;
			}
		}
		delete[] pBuf;
		fclose(srcfp);
	}
	zipCloseFileInZip(zfile);

	return true;
}

bool nyCollectfileInDirtoZip(zipFile zfile, const std::string& filepath, const std::string& parentdirName)
{
	if (NULL == zfile || filepath.empty())
	{
		return false;
	}
	bool bFile = false;
	std::string relativepath = "";
	WIN32_FIND_DATAA findFileData;

	char szpath[MAX_PATH] = { 0 };
	if (::PathIsDirectoryA(filepath.c_str()))
	{
		strcpy_s(szpath, sizeof(szpath) / sizeof(szpath[0]), filepath.c_str());
		int len = strlen(szpath) + strlen("\\*.*") + 1;
		strcat_s(szpath, len, "\\*.*");
	}
	else
	{
		bFile = true;
		strcpy_s(szpath, sizeof(szpath) / sizeof(szpath[0]), filepath.c_str());
	}

	HANDLE hFile = ::FindFirstFileA(szpath, &findFileData);
	if (NULL == hFile)
	{
		return false;
	}
	do
	{
		if (parentdirName.empty())
			relativepath = findFileData.cFileName;
		else
			// 生成zip文件中的相对路径
			relativepath = parentdirName + "\\" + findFileData.cFileName;

		// 如果是目录
		if (findFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
		{
			// 去掉目录中的.当前目录和..前一个目录
			if (strcmp(findFileData.cFileName, ".") != 0 && strcmp(findFileData.cFileName, "..") != 0)
			{
				nyAddfiletoZip(zfile, relativepath, "");

				char szTemp[MAX_PATH] = { 0 };
				strcpy_s(szTemp, filepath.c_str());
				strcat_s(szTemp, "\\");
				strcat_s(szTemp, findFileData.cFileName);
				nyCollectfileInDirtoZip(zfile, szTemp, relativepath);
			}
			continue;
		}
		char szTemp[MAX_PATH] = { 0 };
		if (bFile)
		{
			//注意:处理单独文件的压缩
			strcpy_s(szTemp, filepath.c_str());
		}
		else
		{
			//注意:处理目录文件的压缩
			strcpy_s(szTemp, filepath.c_str());
			strcat_s(szTemp, "\\");
			strcat_s(szTemp, findFileData.cFileName);
		}

		nyAddfiletoZip(zfile, relativepath, szTemp);

	} while (::FindNextFileA(hFile, &findFileData));
	FindClose(hFile);

	return true;
}

/*
* 函数功能 : 压缩文件夹到目录
* 备    注 : dirpathName 源文件/文件夹
*      zipFileName 目的压缩包
*      parentdirName 压缩包内名字(文件夹名)
*/
bool nyCreateZipfromDir(const std::string& dirpathName, const std::string& zipfileName, const std::string& parentdirName)
{
	bool bRet = false;

	/*
	APPEND_STATUS_CREATE    创建追加
	APPEND_STATUS_CREATEAFTER 创建后追加(覆盖方式)
	APPEND_STATUS_ADDINZIP    直接追加
	*/
	zipFile zFile = NULL;
	if (!::PathFileExistsA(zipfileName.c_str()))
	{
		zFile = zipOpen(zipfileName.c_str(), APPEND_STATUS_CREATE);
	}
	else
	{
		zFile = zipOpen(zipfileName.c_str(), APPEND_STATUS_ADDINZIP);
	}
	if (NULL == zFile)
	{
		std::cout << "创建ZIP文件失败" << std::endl;
		return bRet;
	}

	if (nyCollectfileInDirtoZip(zFile, dirpathName, parentdirName))
	{
		bRet = true;
	}

	zipClose(zFile, NULL);

	return bRet;
}

int main(int argc, char* argv[])
{
	std::string dirpath = "D:\\www";                   // 源文件/文件夹
	std::string zipfileName = "D:\\a.zip";           // 目的压缩包

	bool ref = nyCreateZipfromDir(dirpath, zipfileName, "");          // 包内文件名<如果为空则压缩时不指定目录>

	std::cout << "[LyShark] 压缩状态 " << ref << std::endl;
	system("pause");
	return 0;
}

3、代码效果

在这里插入图片描述

Logo

中德AI开发者社区由X.Lab发起,旨在促进中德AI技术交流与合作,汇聚开发者及学者,共同探索前沿AI应用与创新。加入我们,共享资源,共创未来!🚀

更多推荐