前言   项目中要用到一个压缩解压缩的模块, 看了很多文章和源代码, 
都不是很称心, 现在把我自己实现的代码和大家分享.

要求:

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
14class CZipImplement 
15
16public: 
17    CZipImplement(void); 
18    ~CZipImplement(void); 
19
20private: 
21    HZIP hz;          //Zip文件句柄 
22    ZRESULT zr;    //操作返回值 
23    ZIPENTRY ze;  //Zip文件入口 
24
25    CString m_FolderPath;     //folder路径 
26    CString  m_FolderName;  //folder将要被压缩的文件夹名 
27
28private: 
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
52public: 
53    //压缩文件夹接口 
54    BOOL Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath); 
55
56    //解压缩文件夹接口 
57    BOOL Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath); 
58
59public: 
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
 15CZipImplement::CZipImplement(void) 
 16
 17
 18
 19CZipImplement::~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///////////////////////////////////////////////////////////////////////////// 
 31BOOL 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///////////////////////////////////////////////////////////////////////////// 
105BOOL 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///////////////////////////////////////////////////////////////////////////// 
183BOOL 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///////////////////////////////////////////////////////////////////////////// 
215void 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///////////////////////////////////////////////////////////////////////////// 
262void 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///////////////////////////////////////////////////////////////////////////// 
274BOOL 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++开发项目,遇到了很多问题,对于相关的问题和我自己的解决办法将在以后的文章中给出.

使用VC++压缩解压缩文件夹的更多相关文章

  1. linux 压缩当前文件夹下所有文件

    linux zip压缩.压缩当前文件夹下所有文件,压缩为a.zip.命令行的方法是怎样. zip  -r fileName.zip  文件夹名 tar tar命令可以用来压缩打包单文件.多个文件.单个 ...

  2. Linux的压缩/解压缩文件处理 zip & unzip

    Linux的压缩/解压缩命令详解及实例 压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip 另:有些服 ...

  3. albert1017 Linux下压缩某个文件夹(文件夹打包)

    albert1017 Linux下压缩某个文件夹(文件夹打包) tar -zcvf /home/xahot.tar.gz /xahottar -zcvf 打包后生成的文件名全路径 要打包的目录例子:把 ...

  4. VC 获取指定文件夹路径的方法小结

    VC获取指定文件夹路径 flyfish  2010-3-5 一 使用Shell函数 1 获取应用程序的安装路径 TCHAR buf[_MAX_PATH];SHGetSpecialFolderPath( ...

  5. shell 批量压缩指定文件夹及子文件夹内图片

    shell 批量压缩指定文件夹及子文件夹内图片 用户上传的图片,一般都没有经过压缩,造成空间浪费.因此须要编写一个程序,查找文件夹及子文件夹的图片文件(jpg,gif,png),将大于某值的图片进行压 ...

  6. python实现压缩当前文件夹下的所有文件

    import os import zipfile def zipDir(dirpath, outFullName): ''' 压缩指定文件夹 :param dirpath: 目标文件夹路径 :para ...

  7. gulp插件实现压缩一个文件夹下不同目录下的js文件(支持es6)

    gulp-uglify:压缩js大小,只支持es5 安装: cnpm: cnpm i gulp-uglify -D yarn: yarn add gulp-uglify -D 使用: 代码实现1:压缩 ...

  8. Linux下压缩某个文件夹(文件夹打包)

    tar -zcvf /home/xahot.tar.gz /xahottar -zcvf 打包后生成的文件名全路径 要打包的目录例子:把/xahot文件夹打包后生成一个/home/xahot.tar. ...

  9. 项目实战工具类(二):ZipUtils(压缩/解压缩文件相关)

    import android.content.Context; import android.util.Log; import java.io.File; import java.io.FileInp ...

随机推荐

  1. ※数据结构※→☆线性表结构(list)☆============单向循环链表结构(list circular single)(四)

    循环链表是另一种形式的链式存贮结构.它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环. 单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可. 循环链表的 ...

  2. 消息对话框(MessageBox)用法介绍

    在软件中我们经常会弹出个小窗口,给一点点提示.这就会用到消息对话框. 在Win32 API程序中只有MessageBox这一种用法. 而在MFC中就有三各方法: 1.调用API中的MessageBox ...

  3. Reader开发(二)增加PDF阅读功能

    最近任务很多很忙,所以更新博客的速度很慢. 大概上周就为Reader加了一个PDF阅读的功能,但是一直没时间写上来.昨晚找一下文件发现扩展了功能的Demo居然在文件目录下看不到任何文件,但是却显示有文 ...

  4. xss 跨站脚本攻击

    这是一个非常简单的攻击. 两个页面如下: <form action="MyJsp.jsp" method="get"> <input type ...

  5. C++汉字转拼音(转)

    #include<iostream> #include<string> using namespace std; string findLetter(int nCode); s ...

  6. xcode-build/version-bump

    # xcode-build-bump.sh # @desc Auto-increment the build number every time the project is run. # @usag ...

  7. ASP.NET Core 中文文档

    ASP.NET Core 中文文档 翻译计划 五月中旬 .NET Core RC2 如期发布,我们遂决定翻译 ASP.NET Core 文档.我们在 何镇汐先生. 悲梦先生. 张仁建先生和 雷欧纳德先 ...

  8. Python前世今生

    Python前世今生   Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时 ...

  9. 调用QQ截图

    var SHExecInfo: SHELLEXECUTEINFO; begin //截图前隐藏主程序窗口 Form1.Hide; //等待截图执行完成 SHExecInfo.cbSize := siz ...

  10. Web前端,高性能优化

    高性能HTML 一.避免使用iframe iframe也叫内联frame,可将一个HTML文档嵌入另一个HTML文档中. iframe的好处是,嵌入的文档独立于父文档,通常也借此使浏览器模拟多线程.缺 ...