使用VC++壓縮解壓縮檔案夾

來源:互聯網
上載者:User

要求:

 

       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++開發項目,遇到了很多問題,對於相關的問題和我自己的解決辦法將在以後的文章中給出.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.