压缩:可压缩单一文件,也可压缩文件夹里的多个文件(包括文件夹里面的子文件夹)。压缩的目标文件格式无限制:demo文件使用的是.text,.h,.cpp,.png,.bmp,.wav,.mp4等。
解压缩:非覆盖解压缩。
1、codeproject下载地址:http://www.codeproject.com/KB/files/zip_utils.aspx。
如果无法访问,请移驾下载:
https://pan.baidu.com/s/1kZ5_dtUHpSY7PP1z50Z0cA
提取码:tnqc
下载zip库,得到四个文件:zip.h,zip.cpp,unzip.h,unzip.cpp,添加进工程。
2、编译出现错误提示。
解决方法:选中两个源文件右键-属性-配置属性-C/C+±预编译头-不使用预编译头
编译成功。
3、添加压缩类ZipHelper。
3.1关键成员声明。
/*
ZipHelper.h
*/
#pragma once
#include
#include
using namespace std;
#include "./zlib/zip.h"
#include "./zlib/unzip.h"
class ZipHelper
{
public:
ZipHelper();
~ZipHelper();
private:
HZIP m_hz; //Zip文件句柄
ZRESULT m_zr; //操作返回值
ZIPENTRY m_ze; //Zip文件入口
CString m_FolderPath; //folder路径
CString m_FolderName; //folder将要被压缩的文件夹名
int m_nZipCnt;
private:
//实现遍历文件夹
void BrowseFile(CString &strFile);
//获取相对路径
void GetRelativePath(CString& pFullPath, CString& pSubString);
//创建路径
BOOL CreatedMultipleDirectory(wchar_t* direct);
//压缩解压缩接口
BOOL Zip_PackFiles(vector<CString> arr, CString mZipFileFullPath);
BOOL Zip_UnPackFiles(CString mZipFileFullPath, CString mUnPackPath);
//检查文件(夹)存在
BOOL IsFolderExist(CString& strPath);
BOOL IsFileExist(CString& strPath);
public:
void PressFolder(CString strTgt,CString strSrcFolder = "", vector<CString> arrSrcFloder = {});//指定压缩包 单一路径 路径集合
void UnPressFolder(CString strTgt);//指定解压目标
private:
vector<CString> m_arrFileFullName;
};
3.2成员函数实现。
#include "stdafx.h"
#include "ZipHelper.h"
ZipHelper::ZipHelper()
{
m_nZipCnt = 0;
}
ZipHelper::~ZipHelper()
{
}
BOOL ZipHelper::Zip_PackFiles(vector<CString> arr, CString mZipFileFullPath)
{
for (int i = 0; i < arr.size(); ++i)
{
//参数错误
if ((arr[i] == "") || (mZipFileFullPath == ""))
{
//路径异常返回
return FALSE;
}
if (!IsFolderExist(arr[i]) && !IsFileExist(arr[i]))
{
//要被压缩的文件夹不存在
return FALSE;
}
CString tZipFilePath = mZipFileFullPath.Left(mZipFileFullPath.ReverseFind('\\') + 1);
if (!IsFolderExist(tZipFilePath))
{
//ZIP文件存放的文件夹不存在创建它
wchar_t* temp = (wchar_t*)tZipFilePath.GetBuffer(tZipFilePath.GetLength());
if (FALSE == CreatedMultipleDirectory(temp))
{
//创建目录失败
return FALSE;
}
}
//获得文件夹的名字
if (arr[i].Right(1) == '\\')
{
this->m_FolderPath = arr[i].Left(arr[i].GetLength() - 1);
m_FolderName = m_FolderPath.Right(m_FolderPath.GetLength() - m_FolderPath.ReverseFind('\\') - 1);
}
else
{
this->m_FolderPath = arr[i];
m_FolderName = arr[i].Right(arr[i].GetLength() - arr[i].ReverseFind('\\') - 1);
}
/************************************************************************/
//创建ZIP文件
if (m_nZipCnt == 0)
{
m_hz = CreateZip(mZipFileFullPath, 0);
}
if (m_hz == 0)
{
//创建Zip文件失败
return FALSE;
}
//递归文件夹,将获取的文件加入ZIP文件
m_nZipCnt++;
BrowseFile(arr[i]);
//关闭ZIP文件
if (m_nZipCnt == m_arrFileFullName.size())
{
CloseZip(m_hz);
m_nZipCnt = 0;
break;
}
}
/************************************************************************/
CFileFind tFFind;
if (!tFFind.FindFile(mZipFileFullPath))
{
//压缩失败(未发现压缩后的文件)
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// 函数说明: 解压缩文件夹
// 参数说明: [in]: mUnPackPath 解压后文件存放的路径
// mZipFileFullPath ZIP文件的路径
/////////////////////////////////////////////////////////////////////////////
BOOL ZipHelper::Zip_UnPackFiles(CString mZipFileFullPath, CString mUnPackPath)
{
//参数错误
if ((mUnPackPath == "") || (mZipFileFullPath == ""))
{
//路径异常返回
return FALSE;
}
CFileFind tFFind;
if (!tFFind.FindFile(mZipFileFullPath))
{
//压缩失败(未发现压缩文件)
return FALSE;
}
//如果解压缩的路径不存在 试图创建它
CString tZipFilePath = mUnPackPath;
if (!IsFolderExist(tZipFilePath))
{
//解压后存放的文件夹不存在 创建它
wchar_t* temp = (wchar_t*)tZipFilePath.GetBuffer(tZipFilePath.GetLength());
if (FALSE == CreatedMultipleDirectory(temp))
{
//创建目录失败
return FALSE;
}
}
/************************************************************************/
//打开ZIP文件
m_hz = OpenZip(mZipFileFullPath, 0);
if (m_hz == 0)
{
//打开Zip文件失败
return FALSE;
}
m_zr = SetUnzipBaseDir(m_hz, mUnPackPath);
if (m_zr != ZR_OK)
{
//打开Zip文件失败
CloseZip(m_hz);
return FALSE;
}
m_zr = GetZipItem(m_hz, -1, &m_ze);
if (m_zr != ZR_OK)
{
//获取Zip文件内容失败
CloseZip(m_hz);
return FALSE;
}
int numitems = m_ze.index;
for (int i = 0; i < numitems; i++)
{
m_zr = GetZipItem(m_hz, i, &m_ze);
m_zr = UnzipItem(m_hz, i, m_ze.name);
if (i == 100)
{
int x = 1;
}
if (m_zr != ZR_OK)
{
//获取Zip文件内容失败
CloseZip(m_hz);
return FALSE;
}
}
m_nZipCnt = 0;
CloseZip(m_hz);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// 函数说明: 遍历文件夹
// 参数说明: [in]:strFile 遍历的文件夹(此方法会主动向路径末尾添加*.*)
// 返回值:BOOL类型,存在返回TRUE,否则为FALSE
/////////////////////////////////////////////////////////////////////////////
void ZipHelper::BrowseFile(CString &strFile)
{
CFileFind ff;
CString szDir = strFile;
WIN32_FIND_DATAA FindFileData;
FindFirstFile(strFile, &FindFileData);
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)//Folder
{
if (szDir.Right(1) != "\\")
szDir += "\\";
szDir += "*.*";
}
else//File
{
int xx = 21;
}
BOOL res = ff.FindFile(szDir);
while (res)
{
res = ff.FindNextFile();
if (ff.IsDirectory() && !ff.IsDots())
{
//如果是一个子目录,用递归继续往深一层找
CString strPath = ff.GetFilePath();
CString subPath;
GetRelativePath(strPath, subPath);
//将文件添加到ZIP文件
ZipAddFolder(m_hz, subPath);
BrowseFile(strPath);
}
else if (!ff.IsDirectory() && !ff.IsDots())
{
//显示当前访问的文件(完整路径)
CString strPath = ff.GetFilePath();
CString subPath;
GetRelativePath(strPath, subPath);
//将文件添加到ZIP文件
ZipAdd(m_hz, subPath, strPath);
}
}
//关闭
ff.Close();
}
/////////////////////////////////////////////////////////////////////////////
// 函数说明: 获取相对路径
// 参数说明: [in]:pFullPath 当前文件的完整路径 [out] : 解析后的相对路径
/////////////////////////////////////////////////////////////////////////////
void ZipHelper::GetRelativePath(CString& pFullPath, CString& pSubString)
{
pSubString = pFullPath.Right(pFullPath.GetLength() - GetAppPath().GetLength());
}
/////////////////////////////////////////////////////////////////////////////
// 函数说明: 创建多级目录
// 参数说明: [in]: 路径字符串
// 返回值: BOOL 成功True 失败False
/////////////////////////////////////////////////////////////////////////////
BOOL ZipHelper::CreatedMultipleDirectory(wchar_t* direct)
{
std::wstring Directoryname = direct;
if (Directoryname[Directoryname.length() - 1] != '\\')
{
Directoryname.append(1, '\\');
}
std::vector< std::wstring> vpath;
std::wstring strtemp;
BOOL bSuccess = FALSE;
for (int i = 0; i < Directoryname.length(); i++)
{
if (Directoryname[i] != '\\')
{
strtemp.append(1, Directoryname[i]);
}
else
{
vpath.push_back(strtemp);
strtemp.append(1, '\\');
}
}
vector< std::wstring>::const_iterator vIter = vpath.begin();
for (vIter; vIter != vpath.end(); vIter++)
{
bSuccess = CreateDirectory((LPCTSTR)vIter->c_str(), NULL) ? TRUE : FALSE;
}
return bSuccess;
}
/////////////////////////////////////////////////////////////////////////////
// 函数说明: 检查指定的文件夹是否存在
// 参数说明: [in]:strPath 检查的文件夹 (此方法会主动向路径末尾添加*.*)
// 返回值:BOOL类型,存在返回TRUE,否则为FALSE
/////////////////////////////////////////////////////////////////////////////
BOOL ZipHelper::IsFolderExist(CString& strPath)
{
CString sCheckPath = strPath;
if (sCheckPath.Right(1) != '\\')
sCheckPath += '\\';
sCheckPath += "*.*";
WIN32_FIND_DATA wfd;
BOOL rValue = FALSE;
HANDLE hFind = FindFirstFile(sCheckPath, &wfd);
if ((hFind != INVALID_HANDLE_VALUE) &&
(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) || (wfd.dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE))
{
//如果存在并类型是文件夹
rValue = TRUE;
}
FindClose(hFind);
return rValue;
}
BOOL ZipHelper::IsFileExist(CString& strPath)
{
DWORD dwAttrib = GetFileAttributes(strPath);
return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 == (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
void ZipHelper::PressFolder(CString strTgt, CString strSrcFolder, vector<CString> arrSrcFloder)
{
m_arrFileFullName.clear();
if (!strSrcFolder.IsEmpty())
{
m_arrFileFullName.push_back(strSrcFolder);
}
if (!arrSrcFloder.empty())
{
for (auto it : arrSrcFloder)
{
m_arrFileFullName.push_back(it);
}
}
//目的文件夹
string patm_hzipFile = strTgt;
Zip_PackFiles(m_arrFileFullName, patm_hzipFile.c_str());
}
void ZipHelper::UnPressFolder(CString strTgt)
{
if (strTgt.IsEmpty())
return;
string patm_hzipFile = strTgt;
string mUnPackPath = GetAppPath();
Zip_UnPackFiles(patm_hzipFile.c_str(), mUnPackPath.c_str());
}
附上完整demo链接:https://download.csdn.net/download/Struggling_Jeff/12387930
没积分没关系,留邮箱在下看到就发