VC++ 解压有密码的.zip文件


  1. 据说对.rar文件的解压是没有开源库的,而且好多软件都是收费的,因此这里便不再探讨对.rar文件的解压,下面研究一下.zip文件。  
  2.    
  3. 不可否认,zlib是当今应用最广泛的压缩与解压缩.zip文件的免费库之一,zlib是一种事实上的业界标准(不信可以自己去百度),而且用法简单,对于有密码的zip文件也能轻松应对(当然我们首先得知道解压所需的密码)。  
  4.    
  5. 下面我将讲解一下如何用zlib.lib和minizip.lib来对一个带密码的.zip压缩文件进行解压。废话少说,开始分析:  
  6.    
  7. 1. 将zlib.lib和minizip.lib放到工程下(因为是静态库,所以将两个文件与其他工程文件放到同一个目录中即可)  
  8.    
  9. 2. 将ioapi.h和unzip.h和zip.h和zlib.h放到工程下(我为了看着清洁,为这几个文件建立了文件夹--zlib)  
  10.    
  11. 3. 在工程的.cpp文件的头部,添加如下代码:  
  12.    
  13. #include "zlib\unzip.h"  
  14. #include "zlib\zlib.h"  
  15. #include "zlib\zip.h"  
  16.    
  17. #pragma comment( lib, "zlib.lib" )    // 将静态库引用进来  
  18. #pragma comment( lib, "minizip.lib" )  
  19.    
  20. 好,经过以上三条,用zlib所需的环境已准备好(以上文件均可在网上下载到),很简单吧。  
  21. 废话少说,上代码:  
  22.    
  23. 注:因为zip文件对于zlib来说相当于是以文件(个人觉得也可以理解为数据块)的形式存在的,在进行解压时,会把zip中的文件(文件夹)当成一块一块的数据进行读取,因此zlib会从zip文件中按顺序一个一个文件(文件夹)的读取,如果是文件,则写成文件,如果是文件夹,则需要用户来自己创立该文件夹的路径,因为zlib不能往不存在的路径中写文件(这是我经过测试发现的)。以上的注释是下面程序的执行过程  
  24.    
  25. #define ZIP_OPEN_FAILED    1  
  26. #define ZIP_GETGLOBAL_FAILED  2  
  27. #define ZIP_GETFILE_FAILED   3  
  28. #define ZIP_CREATEFILE_FAILED  4  
  29. #define ZIP_OPENPSDFILE_FAILED  5  
  30. #define ZIP_OPENFILE_FAILED   6  
  31. #define ZIP_READFILE_ERR   7  
  32. #define MAX_BUFSIZE     4096 // 从zip文件中一次读取的最大缓冲值  
  33.   
  34. //函数名称:UnzipFile  
  35. //函数功能:解压zip文件  
  36. //输入参数:strFilePath 带解压zip文件的路径+名称  
  37. //     strTmpPath  解压到这个路径下  
  38. //     strPsd    密码  
  39. //返 回 值:参考ConfigInfo.h  
  40. int CUnzip::UnzipFile(CString strFilePath, CString strTmpPath, CString strPsd)  
  41. {  
  42.  unzFile uf = NULL;  
  43.  unz_global_info *p_gInfo = NULL;  
  44.  unz_file_info   *p_fInfo = NULL;  
  45.  p_gInfo = new unz_global_info;  
  46.  p_fInfo = new unz_file_info;  
  47.  CString strZipPath = strFilePath;  
  48.    
  49.    
  50.  uf = unzOpen(strZipPath);     // 打开zip文件,返回文件句柄  
  51.  if (NULL == uf)  
  52.   return ZIP_OPEN_FAILED;     // 打开失败  
  53.  if (UNZ_OK != unzGetGlobalInfo(uf, p_gInfo))// 向*pglobal_info结构体中写入zip的信息  
  54.   return ZIP_GETGLOBAL_FAILED;   // 获取zip信息失败  
  55.  CString strZipFName(_T(""));     // 用于存放szZipFName  
  56.  CString strFolderName(_T(""));  
  57.  CString strDiskPath(_T(""));     // 创建磁盘路径(文件夹)时会用到  
  58.  CString strDiskFile(_T(""));     // 创建磁盘文件时会用到  
  59.  char szZipFName[MAX_PATH] = "0";   // 存放从zip中解析出来的“文件(信息块)”名字  
  60.  char szReadBuf[MAX_BUFSIZE] = "0";  
  61.  int  nNum = 0;       // unzReadCurrentFile读取的字符数  
  62.  DWORD dWrite = 0;       // 实际写入的字节数  
  63.  int nState = strFilePath.ReverseFind(_T('\\'));  
  64.  //strTmpPath += CString(_T("\")) + strFilePath.Mid(nState+1, strFilePath.ReverseFind(_T('.'))-nState-1);  
  65.  CreateFilePath(strTmpPath);     // strFilePath为F:\\file.zip,解压到E:\\TEST下,则先创建目录E:\\TEST\\file  
  66.  for (int i = 0; i < p_gInfo->number_entry; i++)  
  67.  {  
  68.   // for reading the content of the current zipfile, you can open it, read data  
  69.      // from it, and close it (you can close it before reading all the file)  
  70.   if (UNZ_OK != unzGetCurrentFileInfo(uf, p_fInfo, szZipFName, MAX_PATH, NULL, 0, NULL, 0))  
  71.    return ZIP_GETFILE_FAILED;  
  72.   switch (p_fInfo->external_fa)  
  73.   {  
  74.   case FILE_ATTRIBUTE_DIRECTORY:  // 文件夹  
  75.    {  
  76.     FormatDirectorys(szZipFName);  
  77.     strFolderName = szZipFName;  
  78.     strDiskPath = strTmpPath + CString(_T("\")) + strFolderName;  
  79.       
  80.     CreateFilePath(strDiskPath); // 创建目录(文件夹)  
  81.     break;  
  82.    }  
  83.      
  84.   default:       // 文件  
  85.    {  
  86.     FormatDirectorys(szZipFName);  
  87.     strZipFName = szZipFName;  
  88.     strDiskFile = strTmpPath + CString(_T("\")) + strZipFName;  
  89.     HANDLE hFile = CreateFile(strDiskFile, GENERIC_WRITE, // 对文件进行只写访问  
  90.           0,        // 独占对文件的访问  
  91.           NULL, OPEN_ALWAYS,    // 打开已有文件,若存在则直接打开,否则创建新文件  
  92.           FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_WRITE_THROUGH, // 隐藏文件 | 进制对文件写入操作进行缓存以减少数据丢失的可能性  
  93.           NULL);  
  94.     if (INVALID_HANDLE_VALUE == hFile)  
  95.      return ZIP_CREATEFILE_FAILED;      // 文件打开(创建)失败  
  96.     if (strPsd.IsEmpty())  
  97.     {  
  98.      if (UNZ_OK != unzOpenCurrentFile(uf))  
  99.      {  
  100.       CloseHandle(hFile);   // 打开失败  
  101.       return ZIP_OPENFILE_FAILED;  
  102.      }  
  103.     }  
  104.     else  
  105.     {  
  106.      if (UNZ_OK != unzOpenCurrentFilePassword(uf, strPsd))  
  107.      {  
  108.       CloseHandle(hFile);   // 打开有密码的zip压缩包中的文件失败  
  109.       return ZIP_OPENPSDFILE_FAILED;  
  110.      }  
  111.     }  
  112.     while(TRUE)  
  113.     {  
  114.      nNum = 0;  
  115.      memset(szReadBuf, 0, MAX_BUFSIZE);  
  116.      nNum = unzReadCurrentFile(uf, szReadBuf, MAX_BUFSIZE); // 从zip中读数据  
  117.      if (nNum < 0)  
  118.      {  
  119.       unzCloseCurrentFile(uf);  
  120.       CloseHandle(hFile);  
  121.       return ZIP_READFILE_ERR;  
  122.      }  
  123.      else if (nNum == 0)  
  124.      {  
  125.       unzCloseCurrentFile(uf);  
  126.       CloseHandle(hFile);  
  127.       break;  
  128.      }  
  129.      else  
  130.      {  
  131.       if (!WriteFile(hFile, szReadBuf, MAX_BUFSIZE, &dWrite, NULL))// 往本地磁盘写数据  
  132.       {  
  133.        unzCloseCurrentFile(uf);  
  134.        CloseHandle(hFile);  
  135.        return (GetLastError());  
  136.       }  
  137.      }  
  138.     }  
  139.     break;  
  140.    }  
  141.      
  142.   }  
  143.   unzGoToNextFile(uf);  
  144.  }  
  145.  if (uf)  
  146.   unzClose(uf);  
  147.  return -1;  
  148. }  
  149.    
  150. // 在磁盘中创建路径strPath  
  151. void C**Dlg::OnCreateFilePath(CString strPath)  
  152. {  
  153.  int nPos;  
  154.  CString strFolder("");  
  155.  for (nPos = 0; nPos != -1; nPos = strPath.Find("\"))  
  156.  {  
  157.   nPos = strPath.Find("\");  
  158.   strFolder += strPath.Left(nPos);  
  159.   if (!PathFileExists(strFolder))  
  160.   {  
  161.    CreateDirectory(strFolder, NULL);  
  162.   }  
  163.   strPath = strPath.Mid(nPos+1);  
  164.   strFolder += "\";  
  165.  }  
  166. }  

http://blog.csdn.net/educast/article/details/38728399




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值