c++实现压缩解压 zip文件

前言

由于博主需要写软件工程的课设,在没有好点子以及考虑到队友能力不足的情况下,决定写一个zip压缩解压。
我使用了Zip Utils实现这一想法,而我的代码则是对Zip Utils的封装,具体压缩和解压由Zip Utils实现。
画线的文件为Zip Utils提供
c++实现压缩解压 zip文件_第1张图片

//zip_un.h
#pragma once
#include           //添加Windows.h不然会一堆错误
#include              //C++使用string添加string,不要添加string.h
#include 
#include 
#include 
#include 
#include "zip.h"
#include "unzip.h"
using namespace std;

class zip_un {
public:
	int Zip_UnPackFiles(string strZipPath);
	void Zip_PackFiles(string path);
	zip_un();

private:
	HZIP hz;
	void browseFile(string inPath);
	WCHAR* toWchar(string strZipPath);
	vector<string> split(const string& str);
	string connectStr(vector<string>& ret);
	string temporaryPath;
	int index; //用于深度搜索的标识
};


//zip_un.cpp
 #include "zip_un.h"
zip_un::zip_un() {
	index = 0;
}
vector<string> zip_un::split(const string& str){
	vector<string> ret;
	const string pattern = "\\";
	/*if (pattern.empty())
		return ret;*/
	int stat = 0, index = str.find_first_of(pattern, 0);
	while (index != str.npos) {
		if (stat != index)
			ret.push_back(str.substr(stat, index - stat));
		stat = index + 1;
		index = str.find_first_of(pattern, stat);
	}
	if (!str.substr(stat).empty())
		ret.push_back(str.substr(stat));
	return ret;
}
string zip_un::connectStr(vector<string>& ret) {
	string c;
	ret[ret.size() - 1] = ret[ret.size() - 1].substr(0, ret[ret.size() - 1].size() - 4);
	for (int i = 0;i < ret.size();i++) {
		c += ret[i] + "\\";
	}
	return c;
}
int zip_un::Zip_UnPackFiles(string strZipPath){
	string strZipPath_un = strZipPath;
	vector<string> mUn = split(strZipPath);
	const WCHAR* pwUnicode = toWchar(strZipPath_un);
	string a = "mkdir -p " + connectStr(mUn);
	system(a.c_str());  //创建文件
	//解压文件
	//SetCurrentDirectory(_T("D:\\c++_project"));//将进程的工作目录移动到该参数所指的目录下,该目录为winrar.exe的默认文件路径
	SetCurrentDirectoryA(connectStr(mUn).c_str());
	//解压文件会直接在项目的.vcproj目录下进行
	HZIP hz = OpenZip(pwUnicode, NULL);
	
	ZIPENTRY ze;
	GetZipItem(hz, -1, &ze);  // -1给出关于zip文件整体信息
	int numitems = ze.index;
	for (int zi = 0; zi < numitems; zi++)
	{
		ZIPENTRY ze;
		GetZipItem(hz, zi, &ze);
		UnzipItem(hz, zi, ze.name);
		cout << "解压成功" << endl;
	}
	CloseZip(hz);
	return 0;
}

WCHAR* zip_un::toWchar(string strZipPath){
	string strZipPath_un = strZipPath;
	//将路径转为TCHAR类型
	int iUnicode = MultiByteToWideChar(CP_ACP, 0, strZipPath_un.c_str(), strZipPath_un.length(), NULL, 0);
	WCHAR* pwUnicode = new WCHAR[iUnicode + 2];
	if (pwUnicode)
	{
		ZeroMemory(pwUnicode, iUnicode + 2);
	}
	MultiByteToWideChar(CP_ACP, 0, strZipPath_un.c_str(), strZipPath_un.length(), pwUnicode, iUnicode);
	pwUnicode[iUnicode] = '\0';
	pwUnicode[iUnicode + 1] = '\0';
	return pwUnicode;
}

void zip_un::browseFile(string inPath) {
	string path = inPath + "\\*.*", filePath;
	struct _finddata_t fileinfo;
	long handle = _findfirst(path.c_str(), &fileinfo);
	if (handle == -1)
		exit(0);
	do{
		if (fileinfo.attrib & _A_SUBDIR){  //为目录
			//ZipAddFolder(hz, toWchar(fileinfo.name));		
			if (strcmp(fileinfo.name, ".") == 0 || strcmp(fileinfo.name, "..") == 0) continue;
			index++;
			vector<string> aa = split(inPath);
			for (int i = index;i > 0;i--) {
				temporaryPath = temporaryPath + aa[aa.size() - i] + "\\";
			}
			ZipAddFolder(hz, toWchar(temporaryPath + fileinfo.name));
			temporaryPath.clear();
			string dirNew = inPath + "\\" + fileinfo.name;
			browseFile(dirNew);	
			index--;
		} 
		else {
			filePath = inPath + "\\" ;
			vector<string> aa = split(inPath);
			for (int i = index+1;i > 0;i--) {
				temporaryPath = temporaryPath + aa[aa.size() - i] + "\\";
			}
			ZipAdd(hz, toWchar(temporaryPath + fileinfo.name  ), toWchar(filePath  + fileinfo.name));
			temporaryPath.clear();
		}
	} while (!_findnext(handle, &fileinfo));
	_findclose(handle);
}

void zip_un::Zip_PackFiles(string path) {
	string  path_1 = path + ".zip";
	hz = CreateZip(toWchar(path_1), 0);
	browseFile(path);
	CloseZip(hz);
}

包含了压缩解压的实现,下面是样例

#include"zip_un.h"
#include 
void main() {
	zip_un z;
	string strZipPath_un, strZipPath = "D:\\c++_project\\2";
	strZipPath_un = strZipPath + ".zip";
	z.Zip_PackFiles(strZipPath);
}

c++实现压缩解压 zip文件_第2张图片
c++实现压缩解压 zip文件_第3张图片
受限于个人能力不足和Zip Utils的局限,无法解决中文压缩后乱码的问题。

需要注意的是压缩路径的问题,我没有想出特别好的办法。我使用深度搜索,解决这一问题。

参考两位博主的博客
https://blog.csdn.net/qq_37059136/article/details/83510764
使用博主 string转换为 WCHAR* 的思路
https://blog.csdn.net/struggling_jeff/article/details/100857364
参考博主的代码结构
https://www.codeproject.com/Articles/7530/Zip-Utils-Clean-Elegant-Simple-Cplusplus-Win
官方链接

你可能感兴趣的:(c++,zip,windows)