C++Zip压缩解压缩示例(支持递归压缩)

所属分类: 软件编程 / C 语言 阅读数: 107
收藏 0 赞 0 分享



第三方函数、头文件、测试工程下载地址:http://pan.baidu.com/s/1gSfKo

复制代码 代码如下:

// 文件名: ZipFunction.h
#pragma once
#include "zip.h"
#include "unzip.h"

namespace ZipUtils
{
    // ------------------------------------------------------------------------------------------------------------------------
    // Summary:
    //   解压zip文件到指定路径, 并返回解压文件路径和文件名。
    // Parameters:
    //   lpszZipFullName   - 待解压 zip压缩包所在文件夹路径和zip压缩名称; 如"D://00//1.zip"。
    //   szFilePathArr     - 保存的解压后文件的文件名;如"1.jpg"。   
    //   lpszUnZipPath     - 解压出来的文件 所存放位置的完整路径; 如 “D://01”
    //                       此参数省略时,默认解压到exe程序所在文件夹下。
    // Returns:
    //   解压成功返回ZR_OK,解压失败返回错误码。
    // ------------------------------------------------------------------------------------------------------------------------
    ZRESULT ExtractZipToDir(LPCTSTR lpszZipFullName, CStringArray& szFilePathArr, LPCTSTR lpszUnZipPath = NULL);

    // ------------------------------------------------------------------------------------------------------------------------
    // Summary:
    //   压缩指定路径下的文件,并保存压缩包到指定路径。
    // Parameters:
    //   lpszSrcPath        - 待压缩文件所在的路径; 如"D://00"。
    //   lpszDestPath       - 压缩完成后,存放压缩包的路径。
    //                        此参数省略时,默认存放路径为exe程序所在文件的路径。
    //   lpszZipName        - 压缩完成后,压缩的名称;如“MySkin.zip”。
    // Returns:
    //   压缩成功返回ZR_OK,压缩失败返回错误码。
    // ------------------------------------------------------------------------------------------------------------------------
    ZRESULT CompressDirToZip(LPCTSTR lpszSrcPath, LPCTSTR lpszZipName, LPCTSTR lpszDestPath = NULL);
}

复制代码 代码如下:

#include "stdafx.h"
#include "ZipFunction.h"
#include <io.h>

namespace ZipUtils
{
    // 全局变量
    int g_nCount = 0;

    ZRESULT ExtractZipToDir(LPCTSTR lpszZipFullName, CStringArray& szFilePathArr, LPCTSTR lpszUnZipPath)
    {
        TCHAR buffer[MAX_PATH] = {0};
        CString strUnZipPath = lpszUnZipPath;
        DWORD zResult = ZR_OK;

        if (!strUnZipPath.IsEmpty())
        {
            // 如果文件路径不存在先创建,存在不做任何修改
            SHCreateDirectoryEx(NULL, lpszUnZipPath, NULL);
        }
        else
        {
            GetCurrentDirectory(MAX_PATH, (LPTSTR)&buffer);
            strUnZipPath = buffer;
            SHCreateDirectoryEx(NULL, strUnZipPath, NULL);
        }

        HZIP hz = OpenZip(lpszZipFullName, 0);
        ZIPENTRY ze;

        GetZipItem(hz, -1, &ze);
        int numitems = ze.index;

        for (int zi = 0; zi < numitems; zi++)
        {
            ZIPENTRY ze;
            GetZipItem(hz,zi,&ze);
            zResult = UnzipItem(hz, zi, (CString)strUnZipPath+_T("\\")+ze.name);  
            szFilePathArr.Add(ze.name);
            if (zResult != ZR_OK)
            {
#ifndef _UNICODE
                // 判断文件是否存在
                if (_access(szFilePathArr[zi], 0))   
                {
                    // 文件不存在的时候
                    return zResult;
                }
#else
                if (_access((char *)(LPTSTR)(LPCTSTR)szFilePathArr[zi], 0))   
                {
                    // 文件不存在的时候
                    return zResult;
                }
#endif
            }
        }

        CloseZip(hz);
        return zResult;
    }

    ZRESULT DirToZip(LPCTSTR lpszSrcPath, LPCTSTR lpszZipName, HZIP& hz, LPCTSTR lpszDestPath)
    {
        static CString strFileName;
        g_nCount++;
        DWORD zResult = ZR_OK;
        TCHAR buffer[MAX_PATH] = {0};

        CString strDestPath = lpszDestPath;

        if (g_nCount == 1)
        {
            // 这里边的只执行一次
            if (!strDestPath.IsEmpty())
            {
                // 如果解压路径文件夹不存在 先创建,存在 不做任何修改
                SHCreateDirectoryEx(NULL, lpszDestPath, NULL);
            }
            else
            {
                GetCurrentDirectory(MAX_PATH, (LPTSTR)&buffer);
                strDestPath = buffer;
                SHCreateDirectoryEx(NULL, strDestPath, NULL);
            }
            hz = CreateZip((CString)strDestPath+_T("\\")+(CString)lpszZipName, 0);
        }

        HANDLE file;
        WIN32_FIND_DATA fileData;
        file = FindFirstFile((CString)lpszSrcPath+_T("\\*.*"), &fileData);
        FindNextFile(file, &fileData);
        while (FindNextFile(file, &fileData))
        {
            // 如果是一个文件目录
            if(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (strFileName.IsEmpty())
                {
                    ZipAddFolder(hz, fileData.cFileName);
                }
                else
                {
                    ZipAddFolder(hz, strFileName+_T("\\")+fileData.cFileName);
                }

                strFileName = fileData.cFileName;
                // 存在子文件夹 递归调用
                DirToZip((CString)lpszSrcPath+_T("\\")+ fileData.cFileName, lpszZipName, hz, lpszDestPath);
                strFileName.Empty();
            }
            else
            {
                CString strTempPath;
                strTempPath.Format(_T("%s\\%s"), (CString)lpszSrcPath, fileData.cFileName);
                if (strFileName.IsEmpty())
                {
                    ZipAdd(hz, fileData.cFileName, strTempPath);
                }
                else
                {
                    ZipAdd(hz, strFileName+_T("\\")+fileData.cFileName, strTempPath);
                }

                if (zResult != ZR_OK)
                {
                    return zResult;
                }
            }
        }

        return zResult;
    }

    ZRESULT CompressDirToZip(LPCTSTR lpszSrcPath, LPCTSTR lpszZipName, LPCTSTR lpszDestPath)
    {
        HZIP hz;
        DWORD zResult = ZR_OK;
        zResult = DirToZip(lpszSrcPath, lpszZipName,hz, lpszDestPath);
        if(zResult == ZR_OK)
        {
            CloseZip(hz);
        }
        g_nCount = 0;

        return zResult;
    }
}

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多