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