压缩代码

zipHelper.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#ifndef ZIPHELPER_H
#define ZIPHELPER_H
#include <string>
#include "zlib\unzip.h"
#include "zlib\zip.h"

class ZipHelper
{
public:
// 压缩文件/文件夹
bool ZipDir(const std::string& sourcePath, const std::string& zipPath);
ZipHelper();
~ZipHelper();
private:
bool AddFileToZip(zipFile zf, const std::string& relative, const std::string& sourcePath);
bool AddDirToZip(zipFile zf, const std::string& relative);
//
bool InnerWriteFileToZip(zipFile zf, const std::string& path);
};
#endif // ZIPHELPER_H

zipHelper.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#define _CRT_SECURE_NO_WARNINGS

#include "unzipHelper.h"
#include <boost/filesystem.hpp>
#include "logs.h"

ZipHelper::ZipHelper()
{

}

ZipHelper::~ZipHelper()
{

}

bool ZipHelper::AddFileToZip(zipFile zf, const std::string& relativeInZip, const std::string& sourcePath)
{
FILE* fps{ NULL };
int err{ ZIP_ERRNO };
bool ret{ false };
zip_fileinfo zi { 0 };
memset(&zi, 0, sizeof(zip_fileinfo));
std::string newFileName{ relativeInZip };
err = zipOpenNewFileInZip(zf, newFileName.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
if (ZIP_OK != err)
{
LOG_ERROR("add error!");
return false;
}
ret = InnerWriteFileToZip(zf, sourcePath);
err = zipCloseFileInZip(zf);
return ret && (ZIP_OK == err);
}


bool ZipHelper::AddDirToZip(zipFile zf, const std::string& relative)
{
zip_fileinfo zi{ 0 };
memset(&zi, 0, sizeof(zip_fileinfo));
int ret{ ZIP_ERRNO };
std::string newRelative { relative + "/" };
ret = zipOpenNewFileInZip(zf, newRelative.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
if (ZIP_OK != ret)
{
return false;
}
ret = zipCloseFileInZip(zf);
return ret == ZIP_OK;
}

bool ZipHelper::InnerWriteFileToZip(zipFile zf, const std::string& path)
{
FILE* fps = fopen(path.c_str(), "rb");
if (NULL == fps)
{
return false;
}
int err{ ZIP_ERRNO };
do
{
enum {MAX_BUFFER = 40960 };
char buf[MAX_BUFFER];
size_t nRead{ 0 };
while (!feof(fps))
{
nRead = fread(buf, 1, sizeof(buf), fps);
err = zipWriteInFileInZip(zf, buf, nRead);
if (ZIP_OK != err)
{
break;
}
if (ferror(fps))
{
err = ZIP_ERRNO;
break;
}
}
} while (0);
fclose(fps);
return ZIP_OK == err;
}

//目录或者文件压缩为zip文件
bool ZipHelper::ZipDir(const std::string& sourcePath, const std::string& zipPath)
{
if (!boost::filesystem::exists(sourcePath))
{
return false;
}
int ret { ZIP_ERRNO };
boost::filesystem::path home{sourcePath};
zipFile zf = zipOpen(zipPath.c_str(), APPEND_STATUS_CREATE);
if (boost::filesystem::is_directory(sourcePath))
{
// AddFileToZip(newZipFile, home.filename().string(), "");
boost::filesystem::recursive_directory_iterator it;
for (auto& it : boost::filesystem::recursive_directory_iterator(home))
{
boost::filesystem::path relative = boost::filesystem::relative(it.path(), home);
if (boost::filesystem::is_directory(it.path()))
{
AddDirToZip(zf, relative.string());
}
else
{
AddFileToZip(zf, relative.string(), it.path().string());
}
}
}
else if (boost::filesystem::is_regular_file(sourcePath))
{
AddFileToZip(zf, home.filename().string(), home.string());
}
else
{
return false;
}
ret = zipClose(zf, NULL); //关闭zip文件
return ZIP_OK == ret;
}

解压代码

unzipHelper.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma once
#ifndef UNZIPHELPER_H
#define UNZIPHELPER_H
#include <string>
#include "zlib\unzip.h"
#include "zlib\zip.h"
class UnZipHelper
{
public:
UnZipHelper();
~UnZipHelper();
// 解压到文件夹
bool UnzipDir(const std::string& unpackPath, const std::string& zipFilePath);
private:
bool MakeDir(const std::string& path);
int UnzipOneFile(unzFile uf, const unz_file_info& info, const std::string& path);
};

#endif // UNZIPHELPER_H

unzipHelper.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "unzipHelper.h"
#include "logs.h"
//#if __cplusplus >= 201703L
//#include <filesystem>
//#else
#include <boost/filesystem.hpp>
//#endif


#pragma comment(lib, "zlibwapi.lib")


#define BUF_MAX 65535
#define MAX_PATH 260


UnZipHelper::UnZipHelper()
{

}

UnZipHelper::~UnZipHelper()
{

}
bool UnZipHelper::UnzipDir(const std::string& unpackPath, const std::string& zipFilePath)
{
//#if __cplusplus >= 201703L
//#else
//#endif
const char* pwd{ NULL };
unzFile uf = unzOpen(zipFilePath.c_str());
unz_global_info64 gi;
int err{ ZIP_ERRNO };
if (uf == NULL)
{
LOG_ERROR("unzOpen %s error!", zipFilePath.c_str());
return false;
}
if (!MakeDir(unpackPath))
{
return false;
}
boost::filesystem::path root{ unpackPath };
int nRet = unzGoToFirstFile(uf);
while (nRet == UNZ_OK)
{
char szRelative[MAX_PATH];
unz_file_info unZipFileInfo;
err = unzGetCurrentFileInfo(uf, &unZipFileInfo, szRelative, sizeof(szRelative), NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
LOG_ERROR("error %d with zipfile in unzGetCurrentFileInfo\n", err);
break;
}
boost::filesystem::path relative(szRelative);
int l = strlen(szRelative);
if ('\\' == szRelative[l - 1] || '/' == szRelative[l - 1])
{
// 文件夹
auto path = root / relative;
if (!MakeDir(path.string()))
{
return false;
}
nRet = unzGoToNextFile(uf);
continue;
}
// 文件
auto path = root / relative;

if (!MakeDir(path.parent_path().string()))
{
return false;
}
err = UnzipOneFile(uf, unZipFileInfo, path.string());
if (UNZ_OK != err)
{
LOG_ERROR("UnzipOneFile %d", err);
}
nRet = unzGoToNextFile(uf);
}
bool res{ false };
if (UNZ_OK == err && UNZ_END_OF_LIST_OF_FILE == nRet )
{
res = true;
}
err = unzClose(uf);
if (UNZ_OK != err)
{
LOG_ERROR("unzClose %d", err);
}
return res;
}

int UnZipHelper::UnzipOneFile(unzFile uf, const unz_file_info& info, const std::string& path)
{
int err = unzOpenCurrentFilePassword(uf, NULL);
if (UNZ_OK != err)
{
return err;
}
FILE * pFile;
fopen_s(&pFile, path.c_str(), "wb");
if (NULL == pFile)
{
LOG_ERROR("fopen %s error!", path.c_str());
return UNZ_ERRNO;
}
enum { MAX_BUFFER = 256 };
char buffer[MAX_BUFFER];
// 文件信息,后期加上
size_t size = info.uncompressed_size;
while (size > 0)
{
int nRead{ 0 };
if (size > MAX_BUFFER)
{
nRead = MAX_BUFFER;
}
else
{
nRead = size;
}
int nReadBytes = unzReadCurrentFile(uf, buffer, nRead);
int n = fwrite(buffer, nReadBytes, 1, pFile);
if (size >= nReadBytes)
{
size -= nReadBytes;
}
else
{
LOG_ERROR("SIZE ERROR!");
size = 0;
}
}
fclose(pFile);
err = unzCloseCurrentFile(uf);
return err;
}

bool UnZipHelper::MakeDir(const std::string& path)
{
if (boost::filesystem::exists(path))
{
if (!boost::filesystem::is_directory(path))
{
LOG_ERROR("%s is file", path.c_str());
return false;
}
// LOG_INFO("%s dir is exists!", path.c_str());
return true;
}
if (!boost::filesystem::create_directory(path))
{
LOG_ERROR("create dir %s error!", path.c_str());
return false;
}
return true;
}

logs.h

1
2
3
4
5
6
7
8
9
10
11
12
#pragma once

#define LOG_ERROR(fmt, ...) printf("[ERROR] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_WRONG(fmt, ...) printf("[WRONG] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...) printf("[INFO] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_TRACE(fmt, ...) printf("[TRACE] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)

#ifdef _DEBUG
#define LOG_DEBUG(fmt, ...) printf("[DEBUG] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define LOG_DEBUG(fmt, ...) ((void)0)
#endif