源代码: 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;
}