zlib库的使用,可以压缩和解压文件夹

源代码: https://download.csdn.net/download/u011144881/12250915

zipHelper.h

#pragma once
#ifndef ZIP_H
#define ZIP_H
#include <iostream>
#include <fstream>
#include <string>
#include <io.h>
#include <direct.h>
#include "zlib\unzip.h"
#include <zlib\zip.h>
using namespace std;

class cPackFile
{
public:
	//将某个目录或者文件(dirName)压缩为zipFileName(.zip)文件
	void CreateZipFromDir(string dirName, string zipFileName);
	cPackFile();
	~cPackFile();
private:
	//递归添加子目录到zip文件  
	void CollectFilesInDirToZip(zipFile zf, string strPath, string parentDir);

	void AddFileToZip(zipFile zf, string fileNameInZip, string srcFile);
};

static inline bool IsFileExist(string pPath);

class cUnpackFile
{
public:
	cUnpackFile();
	~cUnpackFile();
	void CreateDirFromZip(string dirName, string zipFileName);//解压到文件夹dirName
	void CreateFileFromZip(string fName, string zipFileName);//解压第一个文件到文件fName
};

#endif

zipHelper.cpp

#include "zipHelper.h"

//将文件添加到zip文件中,注意如果源文件srcFile为空则添加空目录    
//fileNameInZip: 在zip文件中的文件名,包含相对路径    
void cPackFile::AddFileToZip(zipFile zf, string fileNameInZip, string srcFile)
{
	FILE* srcfp = NULL;

	//初始化写入zip的文件信息
	//zip_fileinfo zi;
	zip_fileinfo   zi = { 0 };

	zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
		zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
	zi.dosDate = 0;
	zi.internal_fa = 0;
	zi.external_fa = 0;

	//如果srcFile为空,加入空目录    
	string new_file_name = "";
	new_file_name += fileNameInZip;
	if (srcFile == "")
	{
		new_file_name += "/";
	}

	//在zip文件中创建新文件    
	zipOpenNewFileInZip(zf, new_file_name.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
	

	if (srcFile != "")
	{
		//打开源文件    
		fopen_s(&srcfp, srcFile.c_str(), "rb");
		if (srcfp == NULL)
		{
			printf("无法添加文件: %s !\n", srcFile);
			zipCloseFileInZip(zf); //关闭zip文件  
			return;
		}

		//读入源文件并写入zip文件    
		char buf[100 * 1024]; //buffer    
		int numBytes = 0;
		while (!feof(srcfp))
		{
			numBytes = fread(buf, 1, sizeof(buf), srcfp);
			zipWriteInFileInZip(zf, buf, numBytes);
			if (ferror(srcfp))
				break;
		}

		//关闭源文件    
		fclose(srcfp);
	}

	//关闭zip文件    
	zipCloseFileInZip(zf);
}


//递归添加子目录到zip文件    
void cPackFile::CollectFilesInDirToZip(zipFile zf, string strPath, string parentDir)
{
	string allfilestr="";

	allfilestr += strPath;
	allfilestr += "//*.*";//find all files

	long Handle;
	struct _finddata_t FileInfo;

	if ((Handle = _findfirst(allfilestr.c_str(), &FileInfo)) == -1L)//目录不存在
		return;

	string currentPath;
	string fullPath;

	do
	{
		if (strlen(FileInfo.name) == 1 && FileInfo.name[0] == '.'
			|| strlen(FileInfo.name) == 2 && FileInfo.name[0] == '.'&&FileInfo.name[1] == '.')
			continue;//当前文件夹 上一层目录

		if (parentDir.length() != 0)
		{
			fullPath = parentDir;
			fullPath += "/";
			fullPath += FileInfo.name;//生成在zip文件中的相对路径
		}
		else
			fullPath += FileInfo.name;

		currentPath = strPath;
		currentPath += "//";
		currentPath += FileInfo.name;

		if (FileInfo.attrib & _A_SUBDIR)// is a directory
		{
			AddFileToZip(zf, fullPath, ""); //在zip文件中生成目录结构
			CollectFilesInDirToZip(zf, currentPath, fullPath);//递归收集子目录文件    
			continue;
		}
		AddFileToZip(zf, fullPath, currentPath); //将文件添加到zip文件中
	} while (_findnext(Handle, &FileInfo) == 0);//find next file
}

//将某个目录或者文件(dirName)压缩为zipFileName(.zip)文件
void cPackFile::CreateZipFromDir(string dirName, string zipFileName)
{
	long Handle;
	struct _finddata_t FileInfo;

	if ((Handle = _findfirst(dirName.c_str(), &FileInfo)) == -1L)//目录不存在
		return;

	zipFile newZipFile = zipOpen(zipFileName.c_str(), APPEND_STATUS_CREATE); //创建zip文件    
	if (newZipFile == NULL)
	{
		printf("\n无法创建zip文件!");
		return;
	}

	

	if (FileInfo.attrib & _A_SUBDIR)// is a directory
	{
		AddFileToZip(newZipFile, FileInfo.name, "");
		CollectFilesInDirToZip(newZipFile, dirName, FileInfo.name);
	}
	else// is a file
		AddFileToZip(newZipFile, FileInfo.name, dirName);

	zipClose(newZipFile, NULL); //关闭zip文件    
}

cPackFile::cPackFile()
{

}

cPackFile::~cPackFile()
{

}



static inline bool IsFileExist(string pPath)
{
	//return GetFileAttributesA(pPath.c_str()) != INVALID_FILE_ATTRIBUTES;
	std::ifstream ifile(pPath);
	return (bool)ifile;
}

void cUnpackFile::CreateDirFromZip(string dirName, string zipFileName)
{
	bool slashFlag = true;
	unzFile unZipDir = unzOpen(zipFileName.c_str());

	if (unZipDir == NULL)
	{
		printf("无法解压zip文件!");
		return;
	}

	if (!IsFileExist(dirName))
		_mkdir(dirName.c_str());

	int nResult = unzGoToFirstFile(unZipDir);
	unsigned char * buf;

	while (nResult == UNZ_OK)
	{
		char szCurrentFile[260];
		unz_file_info unZipFileInfo;
		unzGetCurrentFileInfo(unZipDir, &unZipFileInfo, szCurrentFile, sizeof(szCurrentFile), NULL, 0, NULL, 0);

		std::string filePath = std::string(szCurrentFile);
		std::string fileName;
		string fileRoot;
		unsigned last_slash_pos = filePath.find_last_of('\\');
		if (last_slash_pos == std::string::npos) {
			last_slash_pos = filePath.find_last_of('/');
			slashFlag = false;
		}
		if (last_slash_pos != std::string::npos)
		{
			fileRoot = dirName;
			if (slashFlag)
				fileRoot += "\\";
			else
				fileRoot += "/";
			std::string filetemp = filePath.substr(0, last_slash_pos);
			fileRoot += filetemp;

			if (!IsFileExist(fileRoot))
				_mkdir(fileRoot.c_str());
			if (last_slash_pos == filePath.length() - 1)
			{
				nResult = unzGoToNextFile(unZipDir);
				continue;//文件夹项
			}
		}

		int size = unZipFileInfo.uncompressed_size;
		buf = new unsigned char[size];
		if (!buf)
		{
			printf("No enough Memory!\n");
			return;
		}
		memset(buf, 0, size*sizeof(char));
		int nReadBytes;
		if (UNZ_OK == unzOpenCurrentFilePassword(unZipDir, NULL))
		{
			nReadBytes = unzReadCurrentFile(unZipDir, buf, size);
			unzCloseCurrentFile(unZipDir);
		}
		FILE * pFile;
		string filePos;
		filePos = dirName;
		if (slashFlag)
			filePos += "\\";
		else
			filePos += "/";

		filePos += filePath;

		fopen_s(&pFile, filePos.c_str(), "wb");
		if (pFile)
			fwrite(buf, nReadBytes, 1, pFile);
		else
			printf("无法打开输出文件 %s \n", filePos);

		fclose(pFile);
		delete buf;

		nResult = unzGoToNextFile(unZipDir);
	}
	unzClose(unZipDir);
}

void cUnpackFile::CreateFileFromZip(string fName, string zipFileName)
{
	bool slashFlag = true;
	unzFile unZipDir = unzOpen(zipFileName.c_str());

	if (unZipDir == NULL)
	{
		printf("无法解压zip文件!");
		return;
	}

	int nResult = unzGoToFirstFile(unZipDir);
	unsigned char * buf;

	if (nResult == UNZ_OK)
	{
		char szCurrentFile[260];
		unz_file_info unZipFileInfo;
		unzGetCurrentFileInfo(unZipDir, &unZipFileInfo, szCurrentFile, sizeof(szCurrentFile), NULL, 0, NULL, 0);

		int size = unZipFileInfo.uncompressed_size;
		buf = new unsigned char[size];
		if (!buf)
		{
			printf("No enough Memory!\n");
			return;
		}
		memset(buf, 0, size*sizeof(char));
		int nReadBytes;
		if (UNZ_OK == unzOpenCurrentFilePassword(unZipDir, NULL))
		{
			nReadBytes = unzReadCurrentFile(unZipDir, buf, size);
			unzCloseCurrentFile(unZipDir);
		}
		FILE * pFile;
		fopen_s(&pFile, fName.c_str(), "wb");
		if (pFile)
			fwrite(buf, nReadBytes, 1, pFile);
		else
			printf("无法打开输出文件 %s \n", fName);

		fclose(pFile);
		delete buf;
	}
	unzClose(unZipDir);
}

cUnpackFile::cUnpackFile()
{

}

cUnpackFile::~cUnpackFile()
{

}

 

main.cpp

#include <Windows.h>
#include <iostream>
#include "zipHelper.h"
using namespace std;

int main(int argc, char** argv) {
	cPackFile packTool;
	cUnpackFile unpackTool;
	//printf("压缩forexample文件夹下的example文件夹及其子文件到forexample文件夹中的example.zip文件中\n");
	packTool.CreateZipFromDir("C:\\Users\\admin\\Desktop\\test\\setup2\\Debug\\forexample\\example", "C:\\Users\\admin\\Desktop\\test\\setup2\\Debug\\forexample\\example.zip");
	//printf("解压缩forexample文件夹下的example.zip文件到到forexample文件夹下的example2文件夹中\n");
	unpackTool.CreateDirFromZip("forexample\\example2", "forexample\\example.zip");
	//printf("压缩forexample\\example\\11.txt文件到forexample\\11.zip文件中\n");
	packTool.CreateZipFromDir("forexample\\example\\11.txt", "forexample\\11.zip");
	//printf("解压缩forexample\\11.zip文件到forexample\\111.txt文件中\n");
	unpackTool.CreateFileFromZip("forexample\\111.txt", "forexample\\11.zip");
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值