zlib是当今应用最广泛的压缩与解压缩.zip文件的免费库之一,zlib是一种事实上的业界标准,而且用法简单,对于有密码的zip文件也能轻松应对(当然我们首先得知道解压所需的密码)。
下面我将讲解一下如何用zlib.lib和minizip.lib来对一个带密码的.zip压缩文件进行解压。分析:
1. 将zlib.lib和minizip.lib放到工程下(因为是静态库,所以将两个文件与其他工程文件放到同一个目录中即可)
2. 将ioapi.h和unzip.h和zip.h和zlib.h放到工程下(我为了看着清洁,为这几个文件建立了文件夹--zlib)
3. 在工程的.cpp文件的头部,添加如下代码:
#include "zlib\unzip.h"
#include "zlib\zlib.h"
#include "zlib\zip.h"
设置库的方法:
方法一:
项目-》属性》链接器-》常规,添加库路径
项目-》属性》链接器-》输入,添加库名
方法二:
#pragma comment( lib, "zlib.lib" ) // 将静态库引用进来
#pragma comment( lib, "minizip.lib" )
// 格式化路径,把'/'改成'\\'
void FormatDirectorys( LPSTR lpszDirectorys )
{
if( lpszDirectorys!= NULL )
{
int i=0;
while( lpszDirectorys[ i ] != _T('\0') )
{
if( lpszDirectorys[ i ] == _T('/') )
{
lpszDirectorys[ i ] = _T('\\');
}
i++;
}
}
}
void UnzipFile(CString strFilePath, CString strTmpPath, CString strPsd){ unz_global_info *p_gInfo = NULL; unz_file_info *p_fInfo = NULL; p_gInfo = new unz_global_info; p_fInfo = new unz_file_info; CString strZipPath = strFilePath; unzFileuf = unzOpen(strZipPath); // 打开zip文件,返回文件句柄 if (NULL == uf) { return ; // 打开失败 } if (UNZ_OK != unzGetGlobalInfo(uf, p_gInfo))// 向*pglobal_info结构体中写入zip的信息 { return ; // 获取zip信息失败 } CString strZipFName(_T("")); // 用于存放szZipFName CString strFolderName(_T("")); CString strDiskPath(_T("")); // 创建磁盘路径(文件夹)时会用到 CString strDiskFile(_T("")); // 创建磁盘文件时会用到 char szZipFName[MAX_PATH] = "0"; // 存放从zip中解析出来的“文件(信息块)”名字 char szReadBuf[4096] = "0"; int nNum = 0; // unzReadCurrentFile读取的字符数 DWORD dWrite = 0; // 实际写入的字节数 int nState = strFilePath.ReverseFind(_T('\\')); CreateFilePath(strTmpPath); // strFilePath为F:\\file.zip,解压到E:\\TEST下,则先创建目录E:\\TEST\\file for (int i = 0; i < p_gInfo->number_entry; i++) { if (UNZ_OK != unzGetCurrentFileInfo(uf, p_fInfo, szZipFName, MAX_PATH, NULL, 0, NULL, 0)) { return ; } switch (p_fInfo->external_fa) { case FILE_ATTRIBUTE_DIRECTORY: // 文件夹 { FormatDirectorys(szZipFName); strFolderName = szZipFName; strDiskPath = strTmpPath + CString(_T("\")) + strFolderName; CreateFilePath(strDiskPath); // 创建目录(文件夹) break; } default: // 文件 { FormatDirectorys(szZipFName); strZipFName = szZipFName; strDiskFile = strTmpPath + CString(_T("\")) + strZipFName; HANDLE hFile = CreateFile(strDiskFile, GENERIC_WRITE, // 对文件进行只写访问 0, // 独占对文件的访问 NULL, OPEN_ALWAYS, // 打开已有文件,若存在则直接打开,否则创建新文件 FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_WRITE_THROUGH, // 隐藏文件 | 进制对文件写入操作进行缓存以减少数据丢失的可能性 NULL); if (INVALID_HANDLE_VALUE == hFile) { return ; // 文件打开(创建)失败 } if (strPsd.IsEmpty())//密码是否存在 { if (UNZ_OK != unzOpenCurrentFile(uf)) { CloseHandle(hFile); // 打开失败 return ; } } else { if (UNZ_OK != unzOpenCurrentFilePassword(uf, strPsd)) { CloseHandle(hFile); // 打开有密码的zip压缩包中的文件失败 return ; } } while(TRUE) { nNum = 0; memset(szReadBuf, 0, MAX_BUFSIZE); nNum = unzReadCurrentFile(uf, szReadBuf, MAX_BUFSIZE); // 从zip中读数据 if (nNum < 0) { unzCloseCurrentFile(uf); CloseHandle(hFile); return ; } else if (nNum == 0) { unzCloseCurrentFile(uf); CloseHandle(hFile); break; } else { if (!WriteFile(hFile, szReadBuf, MAX_BUFSIZE, &dWrite, NULL))// 往本地磁盘写数据 { unzCloseCurrentFile(uf); CloseHandle(hFile); return ; } } } break; } } unzGoToNextFile(uf); } if (uf) { <span style="white-space:pre"> </span>unzClose(uf); } return;}