zip文件解压

来源:互联网 发布:前端性能优化的方式 编辑:程序博客网 时间:2024/05/21 09:31


       1.使用Unicode(支持中文).


       2.使用源代码.(不使用静态或者动态库)


       3.实现文件夹压缩解压缩即可.(不提供单文件压缩和内存压缩)


       4.压缩格式为ZIP.


       5.具有一定的容错能力.(判断用户输入的内容)


 


代码如下:


*********************ZipImplement.h*********************


///////////////////////////////////////////////////////////////////////////// 
// 文件名: 
// 创建者: 
// 创建日期: 2009-09-27 下午 04:51:46 
// 
// 说明:压缩解压缩地图文件夹 
/////////////////////////////////////////////////////////////////////////////


#pragma once


#include "zip.h" 
#include "unzip.h"


class CZipImplement 

public: 
    CZipImplement(void); 
    ~CZipImplement(void);


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


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


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


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


    //创建路径 
    BOOL CreatedMultipleDirectory(wchar_t* direct); 
    ///* 
    //*********************************************************************** 
    //* 函数: TransCStringToTCHAR 
    //* 描述:将CString 转换为 TCHAR* 
    //*********************************************************************** 
    //*/ 
    //TCHAR* CString2TCHAR(CString &str) 
    //{ 
    //    int iLen = str.GetLength(); 
    //    TCHAR* szRs = new TCHAR[iLen]; 
    //    lstrcpy(szRs, str.GetBuffer(iLen)); 
    //    str.ReleaseBuffer(); 
    //    return szRs; 
    //}


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


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


public: 
    //静态方法提供文件夹路径检查 
    static BOOL FolderExist(CString& strPath); 
};


 


*********************ZipImplement.cpp*********************


///////////////////////////////////////////////////////////////////////////// 
// 文件名: 
// 创建者: 
// 创建日期: 2009-09-27 下午 04:51:46 
// 
// 说明:压缩解压缩地图文件夹 
/////////////////////////////////////////////////////////////////////////////


#include "StdAfx.h" 
#include "zipimplement.h" 
#include 
#include 
#include


CZipImplement::CZipImplement(void) 

}


CZipImplement::~CZipImplement(void) 

}


///////////////////////////////////////////////////////////////////////////// 
// 函数说明: 实现压缩文件夹操作 
// 参数说明: [in]: pFilePath         要被压缩的文件夹 
//                         mZipFileFullPath  压缩后的文件名和路径 
// 返回值: 参数有误的情况下返回FALSE,压缩成功后返回TRUE 
// 函数作者: 
// 创建日期: 2009-09-27 下午 04:58:52 
///////////////////////////////////////////////////////////////////////////// 
BOOL CZipImplement::Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath) 

    //参数错误 
    if ((pFilePath == L"") || (mZipFileFullPath == L"")) 
    { 
        //路径异常返回 
        return FALSE ; 
    }


    if(!CZipImplement::FolderExist(pFilePath)) 
    { 
        //要被压缩的文件夹不存在 
        return FALSE ; 
    }


    CString tZipFilePath = mZipFileFullPath.Left(mZipFileFullPath.ReverseFind('//') + 1); 
    if(!CZipImplement::FolderExist(tZipFilePath)) 
    { 
        //ZIP文件存放的文件夹不存在创建它 
        wchar_t* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); 
        if (FALSE == CreatedMultipleDirectory(temp)) 
        { 
            //创建目录失败 
            return FALSE; 
        } 
    }


    //获得文件夹的名字 
    if(pFilePath.Right(1) == L"//") 
    { 
        this->m_FolderPath = pFilePath.Left(pFilePath.GetLength() - 1); 
        m_FolderName = m_FolderPath.Right(m_FolderPath.GetLength() - m_FolderPath.ReverseFind('//') - 1); 
    } 
    else 
    { 
        this->m_FolderPath = pFilePath; 
        m_FolderName = pFilePath.Right(pFilePath.GetLength() - pFilePath.ReverseFind('//') - 1); 
    }


    /************************************************************************/


    //创建ZIP文件 
    hz=CreateZip(mZipFileFullPath,0); 
    if(hz == 0) 
    { 
        //创建Zip文件失败 
        return FALSE; 
    }


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


    /************************************************************************/


    CFileFind tFFind; 
    if (!tFFind.FindFile(mZipFileFullPath)) 
    { 
        //压缩失败(未发现压缩后的文件) 
        return FALSE; 
    }


    return TRUE; 
}


///////////////////////////////////////////////////////////////////////////// 
// 函数说明: 解压缩文件夹 
// 参数说明: [in]: mUnPackPath     解压后文件存放的路径 
//                         mZipFileFullPath  ZIP文件的路径 
// 返回值: 
// 函数作者: 
// 创建日期: 2009-09-27 上午 11:04:28 
///////////////////////////////////////////////////////////////////////////// 
BOOL CZipImplement::Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath) 

    //参数错误 
    if ((mUnPackPath == L"") || (mZipFileFullPath == L"")) 
    { 
        //路径异常返回 
        return FALSE ; 
    }


    CFileFind tFFind; 
    if (!tFFind.FindFile(mZipFileFullPath)) 
    { 
        //压缩失败(未发现压缩文件) 
        return FALSE; 
    }


    //如果解压缩的路径不存在 试图创建它 
    CString tZipFilePath = mUnPackPath; 
    if(!CZipImplement::FolderExist(tZipFilePath)) 
    { 
        //解压后存放的文件夹不存在 创建它 
        wchar_t* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); 
        if (FALSE == CreatedMultipleDirectory(temp)) 
        { 
            //创建目录失败 
            return FALSE; 
        } 
    } 
    /************************************************************************/ 
    //打开ZIP文件 
    hz=OpenZip(mZipFileFullPath,0); 
    if(hz == 0) 
    { 
        //打开Zip文件失败 
        return FALSE; 
    }


    zr=SetUnzipBaseDir(hz,mUnPackPath); 
    if(zr != ZR_OK) 
    { 
        //打开Zip文件失败 
        CloseZip(hz); 
        return FALSE;       
    }


    zr=GetZipItem(hz,-1,&ze); 
    if(zr != ZR_OK) 
    { 
        //获取Zip文件内容失败 
        CloseZip(hz); 
        return FALSE;       
    }


    int numitems=ze.index; 
    for (int i=0; i     { 
        zr=GetZipItem(hz,i,&ze); 
        zr=UnzipItem(hz,i,ze.name);


        if(zr != ZR_OK) 
        { 
            //获取Zip文件内容失败 
            CloseZip(hz); 
            return FALSE;       
        } 
    }


    CloseZip(hz); 
    return TRUE; 
}


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

    CString sCheckPath = strPath;


    if(sCheckPath.Right(1) != L"//") 
        sCheckPath += L"//";


    sCheckPath += L"*.*";


    WIN32_FIND_DATA wfd; 
    BOOL rValue = FALSE;


    HANDLE hFind = FindFirstFile(sCheckPath, &wfd);


    if ((hFind!=INVALID_HANDLE_VALUE) && 
        (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) || (wfd.dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE)) 
    { 
        //如果存在并类型是文件夹 
        rValue = TRUE; 
    }


    FindClose(hFind); 
    return rValue; 
}


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

    CFileFind ff; 
    CString szDir = strFile;


    if(szDir.Right(1) != L"//") 
        szDir += L"//";


    szDir += L"*.*";


    BOOL res = ff.FindFile(szDir); 
    while(res) 
    { 
        res = ff.FindNextFile(); 
        if(ff.IsDirectory() && !ff.IsDots()) 
        { 
            //如果是一个子目录,用递归继续往深一层找 
            CString strPath = ff.GetFilePath();


            CString subPath; 
            GetRelativePath(strPath,subPath); 
            //将文件添加到ZIP文件 
            ZipAddFolder(hz,subPath); 
            BrowseFile(strPath); 
        } 
        else if(!ff.IsDirectory() && !ff.IsDots()) 
        { 
            //显示当前访问的文件(完整路径) 
            CString strPath = ff.GetFilePath(); 
            CString subPath;


            GetRelativePath(strPath,subPath); 
            //将文件添加到ZIP文件 
            ZipAdd(hz,subPath,strPath); 
        } 
    }


    //关闭 
    ff.Close(); 
}


///////////////////////////////////////////////////////////////////////////// 
// 函数说明: 获取相对路径 
// 参数说明: [in]:pFullPath 当前文件的完整路径 [out] : 解析后的相对路径 
// 函数作者: 
// 创建日期: 2009-9-28 上午 11:17:21 
///////////////////////////////////////////////////////////////////////////// 
void CZipImplement::GetRelativePath(CString& pFullPath,CString& pSubString) 

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


///////////////////////////////////////////////////////////////////////////// 
// 函数说明: 创建多级目录 
// 参数说明: [in]: 路径字符串 
// 返回值: BOOL 成功True 失败False 
// 函数作者: 
// 创建日期: 2009-9-28 下午 04:53:20 
///////////////////////////////////////////////////////////////////////////// 
BOOL CZipImplement::CreatedMultipleDirectory(wchar_t* direct) 

    std::wstring Directoryname = direct;


    if (Directoryname[Directoryname.length() - 1] !=  '//') 
    { 
        Directoryname.append(1, '//'); 
    } 
    std::vector< std::wstring> vpath; 
    std::wstring strtemp; 
    BOOL  bSuccess = FALSE; 
    for (int i = 0; i < Directoryname.length(); i++) 
    { 
        if ( Directoryname[i] != '//') 
        { 
            strtemp.append(1,Directoryname[i]);    
        } 
        else 
        { 
            vpath.push_back(strtemp); 
            strtemp.append(1, '//'); 
        } 
    } 
    std::vector:: const_iterator vIter; 
    for (vIter = vpath.begin();vIter != vpath.end(); vIter++) 
    { 
        bSuccess = CreateDirectory(vIter->c_str(), NULL) ? TRUE :FALSE; 
    }


    return bSuccess; 
}


 


=====================以上为源代码=====================


简单说明:


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++开发项目,遇到了很多问题,对于相关的问题和我自己的解决办法将在以后的文章中给出.


分享到: 
上一篇:转 成真 使用ADO封装类的数据库程序开发实例[第二版] (下)
下一篇:将zip文件加入资源


查看评论
5楼 chengy19900808 2012-09-04 09:11发表 [回复]


新建的是什么工程呢?控制台的么?
4楼 lishangzhong2007 2012-02-12 10:19发表 [回复]


我把zip.h unzip.h zip.cpp unzip.cpp 添加到自己的项目中,怎么就有问题了呢。求教
Deleting intermediate files and output files for project 'li3 - Win32 Debug'.
--------------------Configuration: li3 - Win32 Debug--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
li3.cpp
li3Dlg.cpp
unzip.cpp
e:\li\li3\unzip.cpp(4163) : fatal error C1010: unexpected end of file while looking for precompiled header directive
zip.cpp
e:\li\li3\zip.cpp(2831) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Generating Code...
执行 cl.exe 时出错.


li3.exe - 1 error(s), 0 warning(s)
3楼 shixin_0125 2012-02-03 15:59发表 [回复]
原创粉丝点击