跨平台实现zip压缩加密功能

使用zlib将文件夹压缩成zip文件时,需要自己读取文件然后写入zip文件。利用官方下载的zlib包中包含的contrib/minizip/zip.h和zip.c代码提供的函数,可以很容易实现这个功能。

    zip.h和zip.c函数接口介绍:
1. zipOpen  打开、创建zip文件
2. zipOpenNewFileInZip  在zip文件中创建新文件
3. zipWriteInFileInZip  将数据写入zip文件中的文件里
4. zipCloseFileInZip    关闭zip文件中的文件

5. zipClose  关闭zip文件

将某个目录下的所有文件(包括子目录、空目录)压缩到一个zip文件中的代码如下:

伪代码,具体可以参考minizip.c

#define UNICODE
#define _UNICODE

#include "zip.h"


//最终接口:从某个目录创建zip文件
void CreateZipFromDir(const string& dirName, const string& zipFileName);


//将文件添加到zip文件中,注意如果源文件srcFile为空则添加空目录
//fileNameInZip: 在zip文件中的文件名,包含相对路径
void AddFileToZip(zipFile zf, const char* fileNameInZip, const char* srcFile)
{
  FILE* srcfp = NULL;

  //初始化写入zip的文件信息
  zip_fileinfo zi;
  zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
  zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
  zi.dosDate = 0;
  zi.internal_fa = 0;
  zi.external_fa = 0;

  //如果srcFile为空,加入空目录
  char new_file_name[MAX_PATH];
  memset(new_file_name, 0, sizeof(new_file_name));
  strcat(new_file_name, fileNameInZip);
  if (srcFile == NULL)
  {
      strcat(new_file_name, "/");
  }
  
  //在zip文件中创建新文件
  zipOpenNewFileInZip(zf, new_file_name, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);

  if (srcFile != NULL)
  {
      //打开源文件
      srcfp = fopen(srcFile, "rb");
      if (srcfp == NULL)
      {
          cout<<"无法添加文件 "<< string(srcFile)<<endl;
          zipCloseFileInZip(zf); //关闭zip文件
          return;
      }

      //读入源文件并写入zip文件
      char buf[100*1024]; //buffer
      int numBytes = 0;
      while( !feof(srcfp) )
      {
          numBytes = fread(buf, 1, sizeof(buf), srcfp);
          zipWriteInFileInZip(zf, buf, numBytes);
          if( ferror(srcfp) )
              break;
      }

      //关闭源文件
      fclose(srcfp);
  }

  //关闭zip文件
  zipCloseFileInZip(zf);
}


//递归添加子目录到zip文件
void CollectFilesInDirToZip(zipFile zf, const string& strPath, const string& parentDir)
{
  
  string strRelativePath;
  CFileFind finder; 
  bool bWorking = finder.FindFile(strPath + _T("//*.*"));
  while(bWorking) 
  { 
      bWorking = finder.FindNextFile(); 
      if(finder.IsDots())
          continue; 
      
      if (parentDir == _T(""))
          strRelativePath = finder.GetFileName();
      else
          strRelativePath = parentDir + _T("//") + finder.GetFileName(); //生成在zip文件中的相对路径
  
      if(finder.IsDirectory())
      {
          AddFileToZip(zf, W2CA(strRelativePath), NULL); //在zip文件中生成目录结构
          CollectFilesInDirToZip(zf, finder.GetFilePath(), strRelativePath); //递归收集子目录文件
          continue;
      }
      
      AddFileToZip(zf, W2CA(strRelativePath), W2CA(finder.GetFilePath())); //将文件添加到zip文件中
  }
}


//最终接口:从某个目录创建zip文件
void CreateZipFromDir(const string& dirName, const string& zipFileName)
{
  zipFile newZipFile = zipOpen(W2CA(zipFileName), APPEND_STATUS_CREATE); //创建zip文件
  if (newZipFile == NULL)
  {
    cout<<"无法创建zip文件!"<<endl;
    return;
  }
  
  CollectFilesInDirToZip(newZipFile, dirName, "");
  zipClose(newZipFile, NULL); //关闭zip文件
}

解压可以参考

miniunz.c

原文地址:https://www.cnblogs.com/mtcnn/p/9410049.html