[原]使用VC++压缩解压缩文件夹
要求:
1.使用Unicode(支持中文).
2.使用源代码.(不使用静态或者动态库)
3.实现文件夹压缩解压缩即可.(不提供单文件压缩和内存压缩)
4.压缩格式为ZIP.
5.具有一定的容错能力.(判断用户输入的内容)
代码如下:
*********************ZipImplement.h********************
1

/**////////////////////////////////////////////////////////////////////////////// 2
// 文件名: <ZipImplement.h> 3
// 创建者: <hwfly> 4
// 创建日期: 2009-09-27 下午 04:51:46 5
// 6
// 说明:压缩解压缩地图文件夹 7

/**////////////////////////////////////////////////////////////////////////////// 8

9
#pragma once 10

11
#include "zip.h" 12
#include "unzip.h" 13

14
class CZipImplement 15


{ 16
public: 17
CZipImplement(void); 18
~CZipImplement(void); 19

20
private: 21
HZIP hz; //Zip文件句柄 22
ZRESULT zr; //操作返回值 23
ZIPENTRY ze; //Zip文件入口 24

25
CString m_FolderPath; //folder路径 26
CString m_FolderName; //folder将要被压缩的文件夹名 27

28
private: 29
//实现遍历文件夹 30
void BrowseFile(CString &strFile); 31

32
//获取相对路径 33
void GetRelativePath(CString& pFullPath, CString& pSubString); 34

35
//创建路径 36
BOOL CreatedMultipleDirectory(wchar_t* direct); 37

/**////* 38
//*********************************************************************** 39
//* 函数: TransCStringToTCHAR 40
//* 描述:将CString 转换为 TCHAR* 41
//*********************************************************************** 42
//*/ 43
//TCHAR* CString2TCHAR(CString &str) 44
//{ 45
// int iLen = str.GetLength(); 46
// TCHAR* szRs = new TCHAR[iLen]; 47
// lstrcpy(szRs, str.GetBuffer(iLen)); 48
// str.ReleaseBuffer(); 49
// return szRs; 50
//} 51

52
public: 53
//压缩文件夹接口 54
BOOL Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath); 55

56
//解压缩文件夹接口 57
BOOL Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath); 58

59
public: 60
//静态方法提供文件夹路径检查 61
static BOOL FolderExist(CString& strPath); 62
};
*********************ZipImplement.cpp*********************
1

/**////////////////////////////////////////////////////////////////////////////// 2
// 文件名: <ZipImplement.cpp> 3
// 创建者: <hwfly> 4
// 创建日期: 2009-09-27 下午 04:51:46 5
// 6
// 说明:压缩解压缩地图文件夹 7

/**////////////////////////////////////////////////////////////////////////////// 8

9
#include "StdAfx.h" 10
#include "zipimplement.h" 11
#include <direct.h> 12
#include <vector> 13
#include <xstring> 14

15
CZipImplement::CZipImplement(void) 16


{ 17
} 18

19
CZipImplement::~CZipImplement(void) 20


{ 21
} 22

23

/**////////////////////////////////////////////////////////////////////////////// 24
// 函数说明: 实现压缩文件夹操作 25
// 参数说明: [in]: pFilePath 要被压缩的文件夹 26
// mZipFileFullPath 压缩后的文件名和路径 27
// 返回值: 参数有误的情况下返回FALSE,压缩成功后返回TRUE 28
// 函数作者: <hwfly> 29
// 创建日期: 2009-09-27 下午 04:58:52 30

/**////////////////////////////////////////////////////////////////////////////// 31
BOOL CZipImplement::Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath) 32


{ 33
//参数错误 34
if ((pFilePath == L"") || (mZipFileFullPath == L"")) 35

{ 36
//路径异常返回 37
return FALSE ; 38
} 39

40
if(!CZipImplement::FolderExist(pFilePath)) 41

{ 42
//要被压缩的文件夹不存在 43
return FALSE ; 44
} 45

46
CString tZipFilePath = mZipFileFullPath.Left(mZipFileFullPath.ReverseFind('\\') + 1); 47
if(!CZipImplement::FolderExist(tZipFilePath)) 48

{ 49
//ZIP文件存放的文件夹不存在创建它 50
wchar_t* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); 51
if (FALSE == CreatedMultipleDirectory(temp)) 52

{ 53
//创建目录失败 54
return FALSE; 55
} 56
} 57

58
//获得文件夹的名字 59
if(pFilePath.Right(1) == L"\\") 60

{ 61
this->m_FolderPath = pFilePath.Left(pFilePath.GetLength() - 1); 62
m_FolderName = m_FolderPath.Right(m_FolderPath.GetLength() - m_FolderPath.ReverseFind('\\') - 1); 63
} 64
else 65

{ 66
this->m_FolderPath = pFilePath; 67
m_FolderName = pFilePath.Right(pFilePath.GetLength() - pFilePath.ReverseFind('\\') - 1); 68
} 69

70

/**//************************************************************************/ 71

72
//创建ZIP文件 73
hz=CreateZip(mZipFileFullPath,0); 74
if(hz == 0) 75

{ 76
//创建Zip文件失败 77
return FALSE; 78
} 79

80
//递归文件夹,将获取的问价加入ZIP文件 81
BrowseFile(pFilePath); 82
//关闭ZIP文件 83
CloseZip(hz); 84

85

/**//************************************************************************/ 86

87
CFileFind tFFind; 88
if (!tFFind.FindFile(mZipFileFullPath)) 89

{ 90
//压缩失败(未发现压缩后的文件) 91
return FALSE; 92
} 93

94
return TRUE; 95
} 96

97

/**////////////////////////////////////////////////////////////////////////////// 98
// 函数说明: 解压缩文件夹 99
// 参数说明: [in]: mUnPackPath 解压后文件存放的路径 100
// mZipFileFullPath ZIP文件的路径 101
// 返回值: 102
// 函数作者: <hwfly> 103
// 创建日期: 2009-09-27 上午 11:04:28 104

/**////////////////////////////////////////////////////////////////////////////// 105
BOOL CZipImplement::Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath) 106


{ 107
//参数错误 108
if ((mUnPackPath == L"") || (mZipFileFullPath == L"")) 109

{ 110
//路径异常返回 111
return FALSE ; 112
} 113

114
CFileFind tFFind; 115
if (!tFFind.FindFile(mZipFileFullPath)) 116

{ 117
//压缩失败(未发现压缩文件) 118
return FALSE; 119
} 120

121
//如果解压缩的路径不存在 试图创建它 122
CString tZipFilePath = mUnPackPath; 123
if(!CZipImplement::FolderExist(tZipFilePath)) 124

{ 125
//解压后存放的文件夹不存在 创建它 126
wchar_t* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); 127
if (FALSE == CreatedMultipleDirectory(temp)) 128

{ 129
//创建目录失败 130
return FALSE; 131
} 132
} 133

/**//************************************************************************/ 134
//打开ZIP文件 135
hz=OpenZip(mZipFileFullPath,0); 136
if(hz == 0) 137

{ 138
//打开Zip文件失败 139
return FALSE; 140
} 141

142
zr=SetUnzipBaseDir(hz,mUnPackPath); 143
if(zr != ZR_OK) 144

{ 145
//打开Zip文件失败 146
CloseZip(hz); 147
return FALSE; 148
} 149

150
zr=GetZipItem(hz,-1,&ze); 151
if(zr != ZR_OK) 152

{ 153
//获取Zip文件内容失败 154
CloseZip(hz); 155
return FALSE; 156
} 157

158
int numitems=ze.index; 159
for (int i=0; i<numitems; i++) 160

{ 161
zr=GetZipItem(hz,i,&ze); 162
zr=UnzipItem(hz,i,ze.name); 163

164
if(zr != ZR_OK) 165

{ 166
//获取Zip文件内容失败 167
CloseZip(hz); 168
return FALSE; 169
} 170
} 171

172
CloseZip(hz); 173
return TRUE; 174
} 175

176

/**////////////////////////////////////////////////////////////////////////////// 177
// 函数说明: 检查指定的文件夹是否存在 178
// 参数说明: [in]:strPath 检查的文件夹 (此方法会主动向路径末尾添加*.*) 179
// 返回值:BOOL类型,存在返回TRUE,否则为FALSE 180
// 函数作者: <hwfly> 181
// 创建日期: 2009-09-27 下午 02:16:36 182

/**////////////////////////////////////////////////////////////////////////////// 183
BOOL CZipImplement::FolderExist(CString& strPath) 184


{ 185
CString sCheckPath = strPath; 186

187
if(sCheckPath.Right(1) != L"\\") 188
sCheckPath += L"\\"; 189

190
sCheckPath += L"*.*"; 191

192
WIN32_FIND_DATA wfd; 193
BOOL rValue = FALSE; 194

195
HANDLE hFind = FindFirstFile(sCheckPath, &wfd); 196

197
if ((hFind!=INVALID_HANDLE_VALUE) && 198
(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) || (wfd.dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE)) 199

{ 200
//如果存在并类型是文件夹 201
rValue = TRUE; 202
} 203

204
FindClose(hFind); 205
return rValue; 206
} 207

208

/**////////////////////////////////////////////////////////////////////////////// 209
// 函数说明: 遍历文件夹 210
// 参数说明: [in]:strFile 遍历的文件夹(此方法会主动向路径末尾添加*.*) 211
// 返回值:BOOL类型,存在返回TRUE,否则为FALSE 212
// 函数作者: <hwfly> 213
// 创建日期: 2009-09-27 下午 02:16:36 214

/**////////////////////////////////////////////////////////////////////////////// 215
void CZipImplement::BrowseFile(CString &strFile) 216


{ 217
CFileFind ff; 218
CString szDir = strFile; 219

220
if(szDir.Right(1) != L"\\") 221
szDir += L"\\"; 222

223
szDir += L"*.*"; 224

225
BOOL res = ff.FindFile(szDir); 226
while(res) 227

{ 228
res = ff.FindNextFile(); 229
if(ff.IsDirectory() && !ff.IsDots()) 230

{ 231
//如果是一个子目录,用递归继续往深一层找 232
CString strPath = ff.GetFilePath(); 233

234
CString subPath; 235
GetRelativePath(strPath,subPath); 236
//将文件添加到ZIP文件 237
ZipAddFolder(hz,subPath); 238
BrowseFile(strPath); 239
} 240
else if(!ff.IsDirectory() && !ff.IsDots()) 241

{ 242
//显示当前访问的文件(完整路径) 243
CString strPath = ff.GetFilePath(); 244
CString subPath; 245

246
GetRelativePath(strPath,subPath); 247
//将文件添加到ZIP文件 248
ZipAdd(hz,subPath,strPath); 249
} 250
} 251

252
//关闭 253
ff.Close(); 254
} 255

256

/**////////////////////////////////////////////////////////////////////////////// 257
// 函数说明: 获取相对路径 258
// 参数说明: [in]:pFullPath 当前文件的完整路径 [out] : 解析后的相对路径 259
// 函数作者: <hwfly> 260
// 创建日期: 2009-9-28 上午 11:17:21 261

/**////////////////////////////////////////////////////////////////////////////// 262
void CZipImplement::GetRelativePath(CString& pFullPath,CString& pSubString) 263


{ 264
pSubString = pFullPath.Right(pFullPath.GetLength() - this->m_FolderPath.GetLength() + this->m_FolderName.GetLength()); 265
} 266

267

/**////////////////////////////////////////////////////////////////////////////// 268
// 函数说明: 创建多级目录 269
// 参数说明: [in]: 路径字符串 270
// 返回值: BOOL 成功True 失败False 271
// 函数作者: <hwfly> 272
// 创建日期: 2009-9-28 下午 04:53:20 273

/**////////////////////////////////////////////////////////////////////////////// 274
BOOL CZipImplement::CreatedMultipleDirectory(wchar_t* direct) 275


{ 276
std::wstring Directoryname = direct; 277

278
if (Directoryname[Directoryname.length() - 1] != '\\') 279

{ 280
Directoryname.append(1, '\\'); 281
} 282
std::vector< std::wstring> vpath; 283
std::wstring strtemp; 284
BOOL bSuccess = FALSE; 285
for (int i = 0; i < Directoryname.length(); i++) 286

{ 287
if ( Directoryname[i] != '\\') 288

{ 289
strtemp.append(1,Directoryname[i]); 290
} 291
else 292

{ 293
vpath.push_back(strtemp); 294
strtemp.append(1, '\\'); 295
} 296
} 297
std::vector<std::wstring>:: const_iterator vIter; 298
for (vIter = vpath.begin();vIter != vpath.end(); vIter++) 299

{ 300
bSuccess = CreateDirectory(vIter->c_str(), NULL) ? TRUE :FALSE; 301
} 302

303
return bSuccess; 304
}
=====================以上为源代码=====================
简单说明:
1.使用VS2003编写.
2.WinXp sp2下运行测试通过.
3.为了简化算法,使用了很多MFC提供的函数, 如果要移植到标准C++请重新实现部分函数.
4.压缩算法采用了ljw1004 这位高手的算法.
5."zip.h" 和 "unzip.h"以及实现请至 http://www.codeproject.com/KB/files/zip_utils.aspx 下载, 下载的源文件中有示例程序可以参考.
将下载后的 zip.h unzip.h zip.cpp unzip.cpp 添加到自己的项目中.
后记:第一次使用VC++开发项目,遇到了很多问题,对于相关的问题和我自己的解决办法将在以后的文章中给出.

浙公网安备 33010602011771号