zoukankan      html  css  js  c++  java
  • 跨平台实现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

  • 相关阅读:
    fastjson报错 java.lang.StackOverflowError
    关于mybatis使用foreach插入速度较慢的问题
    selectKey返回查询的LAST_INSERT_ID的总是1
    使用java制作https证书
    cf 809
    多校 2009 3
    多校 2009 2
    多校 2009 1
    codeforces 808
    hdu 4734 数位DP
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9410049.html
Copyright © 2011-2022 走看看