zoukankan      html  css  js  c++  java
  • 跨平台的zip文件压缩处理,支持压缩解压文件夹

    根据minizip改写的模块,需要zlib支持

    输出的接口:

     1 #define RG_ZIP_FILE_REPLACE    0
     2 #define RG_ZIP_FILE_APPEND            1
     3 
     4 //压缩文件夹目录,递归压缩
     5 //szDir是需要压缩的目录,dstLevel是压缩的目录在压缩包里面的层次标识
     6 //可直接指定""
     7 //szZipFile压缩包的文件名
     8 //replaceFlag指定替换或者是追加进压缩包
     9 int DoZipDir(const char* szDir, const char* dstLevel, const char* szZipFile, int replaceFlag);
    10 
    11 //压缩单个文件,szFile是文件名,其它参数解析同上
    12 int DoZipFile(const char* szFile, const char* dstLevel, const char* szZipFile, int replaceFlag);
    13 
    14 //解压缩文件
    15 //szZipFile是需要解压的压缩包文件名
    16 //指定需要解压到的目录,直接指定为"",解压至当前目录
    17 int DoUnzip(const char* szZipFile, const char* szTargetDir);
    18 
    19 //从压缩包里面解压单个文件出来
    20 //srcFileToExtract对应压缩文件时的dstLevel
    21 //其它参数解析同上
    22 int DoUnzipFile(const char* szZipFile, const char* srcFileToExtract, const char* szTargetDir);  

    本文仅仅提供封装的api,zlib库和info-zip请自行下载

    其它涉及的代码可以下载minizip或者info-zip,推荐使用minizip,本代码是在minizip的基础上修改而来,支持跨平台

      1 /*
      2 minizip.c
      3 Version 1.1, February 14h, 2010
      4 sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
      5 
      6 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
      7 
      8 Modifications of Unzip for Zip64
      9 Copyright (C) 2007-2008 Even Rouault
     10 
     11 Modifications for Zip64 support on both zip and unzip
     12 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
     13 */
     14 
     15 #ifdef _DEBUG
     16 #pragma comment(lib, "../../lib/win32/libzd.lib")
     17 #else
     18 #pragma comment(lib, "../../lib/win32/libz.lib")
     19 #endif
     20 
     21 #ifndef _WIN32
     22 #ifndef __USE_FILE_OFFSET64
     23 #define __USE_FILE_OFFSET64
     24 #endif
     25 #ifndef __USE_LARGEFILE64
     26 #define __USE_LARGEFILE64
     27 #endif
     28 #ifndef _LARGEFILE64_SOURCE
     29 #define _LARGEFILE64_SOURCE
     30 #endif
     31 #ifndef _FILE_OFFSET_BIT
     32 #define _FILE_OFFSET_BIT 64
     33 #endif
     34 #endif
     35 
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <time.h>
     40 #include <errno.h>
     41 #include <fcntl.h>
     42 
     43 #ifdef _LINUX
     44 # include <utime.h>
     45 # include <sys/types.h>
     46 # include <sys/stat.h>
     47 # include <unistd.h>
     48 #include <dirent.h>
     49 #else
     50 # include <direct.h>
     51 # include <io.h>
     52 #endif
     53 
     54 #include "zip.h"
     55 #include "stdstring.h"
     56 #include <vector>
     57 #include "comfun.h"
     58 
     59 using namespace std;
     60 
     61 // #ifdef _WIN32
     62 // #define USEWIN32IOAPI
     63 // #include "iowin32.h"
     64 // #endif
     65 
     66 
     67 
     68 #define WRITEBUFFERSIZE (16384)
     69 #define MAXFILENAME (256)
     70 
     71 #ifdef _WIN32
     72 static uLong filetime(const char *f, tm_zip *tmzip, uLong *dt)
     73 /*char *f;                 name of file to get info on */
     74  /* tm_zip *tmzip;            return value: access, modific. and creation times */
     75  /*uLong *dt;             dostime */
     76 {
     77     int ret = 0;
     78     {
     79         FILETIME ftLocal;
     80         HANDLE hFind;
     81         WIN32_FIND_DATAA ff32;
     82 
     83         hFind = FindFirstFileA(f,&ff32);
     84         if (hFind != INVALID_HANDLE_VALUE)
     85         {
     86             FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
     87             FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
     88             FindClose(hFind);
     89             ret = 1;
     90         }
     91     }
     92     return ret;
     93 }
     94 #else
     95 #ifdef _LINUX
     96 static uLong filetime(const char *f, tm_zip *tmzip, uLong *dt)
     97  /*char *f;               name of file to get info on */
     98 /*tm_zip *tmzip;          return value: access, modific. and creation times */
     99 /*uLong *dt;              dostime */
    100 {
    101     int ret=0;
    102     struct stat s;        /* results of stat() */
    103     struct tm* filedate;
    104     time_t tm_t=0;
    105 
    106     if (strcmp(f,"-")!=0)
    107     {
    108         char name[MAXFILENAME+1];
    109         int len = strlen(f);
    110         if (len > MAXFILENAME)
    111             len = MAXFILENAME;
    112 
    113         strncpy(name, f,MAXFILENAME-1);
    114         /* strncpy doesnt append the trailing NULL, of the string is too long. */
    115         name[ MAXFILENAME ] = '';
    116 
    117         if (name[len - 1] == '/')
    118             name[len - 1] = '';
    119         /* not all systems allow stat'ing a file with / appended */
    120         if (stat(name,&s)==0)
    121         {
    122             tm_t = s.st_mtime;
    123             ret = 1;
    124         }
    125     }
    126     filedate = localtime(&tm_t);
    127 
    128     tmzip->tm_sec  = filedate->tm_sec;
    129     tmzip->tm_min  = filedate->tm_min;
    130     tmzip->tm_hour = filedate->tm_hour;
    131     tmzip->tm_mday = filedate->tm_mday;
    132     tmzip->tm_mon  = filedate->tm_mon ;
    133     tmzip->tm_year = filedate->tm_year;
    134 
    135     return ret;
    136 }
    137 #else
    138 uLong filetime(char *f, tm_zip *tmzip, uLong *dt)
    139 {
    140     return 0;
    141 }
    142 #endif
    143 #endif
    144 
    145 static int check_exist_file(const char* filename)
    146 {
    147     FILE* ftestexist;
    148     int ret = 1;
    149     ftestexist = fopen64(filename,"rb");
    150     if (ftestexist==NULL)
    151         ret = 0;
    152     else
    153         fclose(ftestexist);
    154 
    155     return ret;
    156 }
    157 
    158 static int isLargeFile(const char* filename)
    159 {
    160     int largeFile = 0;
    161     ZPOS64_T pos = 0;
    162     FILE* pFile = fopen64(filename, "rb");
    163 
    164     if(pFile != NULL)
    165     {
    166         int n = fseeko64(pFile, 0, SEEK_END);
    167 
    168         pos = ftello64(pFile);
    169 
    170         if(pos >= 0xffffffff)
    171             largeFile = 1;
    172 
    173         fclose(pFile);
    174     }
    175 
    176     return largeFile;
    177 }
    178 
    179 static int DoZipFile(zipFile zf, const char* srcFile, const char* dstLevel)
    180 {
    181     if(zf == NULL || srcFile == NULL) return __LINE__;
    182 
    183     int err=0;
    184     int size_buf=0;
    185     void* buf=NULL;
    186     FILE * fin;
    187     int size_read;
    188     const char* filenameinzip = srcFile;
    189     const char *savefilenameinzip;
    190     zip_fileinfo zi;
    191     int zip64 = 0;
    192 
    193     zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
    194         zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
    195     zi.dosDate = 0;
    196     zi.internal_fa = 0;
    197     zi.external_fa = 0;
    198     filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
    199 
    200     zip64 = isLargeFile(filenameinzip);
    201 
    202     /* The path name saved, should not include a leading slash. */
    203     /*if it did, windows/xp and dynazip couldn't read the zip file. */
    204     savefilenameinzip = dstLevel;
    205     while( savefilenameinzip[0] == '\' || savefilenameinzip[0] == '/' )
    206     {
    207         savefilenameinzip++;
    208     }
    209 
    210     err = zipOpenNewFileInZip3_64(zf, savefilenameinzip, &zi,
    211         NULL, 0, NULL, 0, NULL /* comment*/,
    212         Z_DEFLATED,
    213         Z_DEFAULT_COMPRESSION,0,
    214         -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
    215         NULL, 0, zip64);
    216 
    217     if (err != ZIP_OK)
    218         printf("error in opening %s in zipfile
    ",filenameinzip);
    219     else
    220     {
    221         fin = fopen64(filenameinzip,"rb");
    222         if (fin==NULL)
    223         {
    224             err=ZIP_ERRNO;
    225             printf("error in opening %s for reading
    ",filenameinzip);
    226         }
    227     }
    228 
    229     if (err == ZIP_OK)
    230     {
    231         size_buf = WRITEBUFFERSIZE;
    232         buf = (void*)malloc(size_buf);
    233         if (buf==NULL)
    234         {
    235             printf("Error allocating memory
    ");
    236             err = ZIP_INTERNALERROR;
    237         }
    238         else
    239         {
    240             do
    241             {
    242                 err = ZIP_OK;
    243                 size_read = (int)fread(buf,1,size_buf,fin);
    244                 if (size_read < size_buf)
    245                     if (feof(fin)==0)
    246                     {
    247                         printf("error in reading %s
    ",filenameinzip);
    248                         err = ZIP_ERRNO;
    249                     }
    250 
    251                     if (size_read>0)
    252                     {
    253                         err = zipWriteInFileInZip (zf,buf,size_read);
    254                         if (err<0)
    255                         {
    256                             printf("error in writing %s in the zipfile
    ",
    257                                 filenameinzip);
    258                         }
    259 
    260                     }
    261             } while ((err == ZIP_OK) && (size_read>0));
    262 
    263             free(buf);
    264         }
    265     }
    266 
    267     if (fin)
    268         fclose(fin);
    269 
    270     if (err<0)
    271         err=ZIP_ERRNO;
    272     else
    273     {
    274         err = zipCloseFileInZip(zf);
    275         if (err!=ZIP_OK)
    276             printf("error in closing %s in the zipfile
    ",
    277             filenameinzip);
    278     }
    279 
    280     return 0;
    281 }
    282 
    283 int DoZipFile(const char* strFile, const char* dstLevel, const char* strZipFile, int replaceFlag)
    284 {
    285     int openMode = APPEND_STATUS_CREATE;
    286     if (check_exist_file(strZipFile))
    287     {
    288         if (replaceFlag == RG_ZIP_FILE_APPEND)
    289         {
    290             openMode = APPEND_STATUS_ADDINZIP;
    291         }
    292         else
    293         {
    294             openMode = APPEND_STATUS_CREATE;
    295         }
    296     }
    297 
    298     zipFile zf;
    299     zf = zipOpen64(strZipFile, openMode);
    300     if (zf)
    301     {
    302         CStdString strDstLevel;
    303         if(dstLevel) strDstLevel = dstLevel;
    304         strDstLevel.Trim();
    305         if(strDstLevel.IsEmpty())
    306         {
    307             strDstLevel = strFile;
    308             if(strDstLevel.Right(1) == "\" || strDstLevel.Right(1) == "/")
    309                 strDstLevel = strDstLevel.Left(strDstLevel.GetLength() - 1);
    310             int nFind = strDstLevel.ReverseFind('\');
    311             if(nFind == -1) nFind = strDstLevel.ReverseFind('/');
    312             if(nFind != -1) 
    313                 strDstLevel = strDstLevel.Mid(nFind);
    314         }
    315 
    316         if (strDstLevel.Left(1) == "\" || strDstLevel.Left(1) == "/") 
    317             strDstLevel = strDstLevel.Right(strDstLevel.GetLength() - 1);
    318 
    319         DoZipFile(zf, strFile, strDstLevel.c_str());
    320         zipClose(zf, NULL);
    321         return 0;
    322     }
    323 
    324     return 0;
    325 }
    326 
    327 static int GetFilesFromDir(const char* strDir, vector<CStdString> &_fileInfo)
    328 {
    329 
    330 #ifdef _WIN32
    331     CStdString strFind = strDir;
    332     CStdString strPath;
    333     if (strFind.Right(1) != "\")
    334     {
    335         strFind += "\";
    336     }
    337     strPath = strFind;
    338     strFind += "*.*";
    339     
    340     WIN32_FIND_DATA wfd;
    341     HANDLE hFind = FindFirstFile(strFind, &wfd);
    342     if (hFind != INVALID_HANDLE_VALUE)
    343     {
    344         while(FindNextFile(hFind, &wfd))
    345         {
    346             if (strcmp(wfd.cFileName, ".") == 0 || strcmp(wfd.cFileName, "..") == 0)
    347             {
    348                 continue;
    349             }
    350             CStdString strFilePath = strPath + wfd.cFileName;
    351             if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    352             {
    353                 GetFilesFromDir(strFilePath.c_str(), _fileInfo);
    354             }
    355             else
    356             {
    357                 _fileInfo.push_back(strFilePath);
    358             }
    359         }
    360         FindClose(hFind);
    361         return 0;
    362     }
    363     
    364     return __LINE__;
    365 #else
    366     struct stat     statbuf;
    367     struct dirent    *dirp;
    368     DIR                *dp;
    369     const char* szPath = strDir;
    370 
    371     if(lstat(szPath, &statbuf) < 0)
    372     {
    373         perror("lstat");
    374         return __LINE__;
    375     }
    376     if(S_ISDIR(statbuf.st_mode) == 0)
    377     {
    378         _fileInfo.push_back(szPath);
    379         return 0;
    380     }
    381 
    382     if((dp = opendir(szPath)) == NULL)
    383     {
    384         perror("opendir");
    385         return __LINE__;
    386     }
    387 
    388     while((dirp = readdir(dp)) != NULL)
    389     {
    390         if(strcmp(dirp->d_name, ".") == 0 ||
    391             strcmp(dirp->d_name, "..") == 0)
    392             continue;
    393 
    394         std::string subDir = string(szPath) + "/";
    395         subDir += dirp->d_name;
    396         if(dirp->d_type == DT_REG)
    397         {
    398             _fileInfo.push_back(subDir);
    399         }
    400         else if(dirp->d_type == DT_DIR)    
    401         {
    402             GetFilesFromDir(subDir.c_str(), _fileInfo);
    403         }
    404     }
    405 
    406     closedir(dp);
    407 #endif
    408 }
    409 
    410 int DoZipDir(const char* strDir, const char* dstLevel, const char* strZipFile, int replaceFlag)
    411 {
    412     int openMode = APPEND_STATUS_CREATE;
    413     if(check_exist_file(strZipFile))
    414     {
    415         if (replaceFlag == RG_ZIP_FILE_APPEND)
    416         {
    417             openMode = APPEND_STATUS_ADDINZIP;
    418         }
    419         else
    420         {
    421             remove(strZipFile);
    422             openMode = APPEND_STATUS_CREATE;
    423         }
    424     }
    425 
    426     CStdString strDstLevel;
    427     if(dstLevel) strDstLevel= dstLevel;
    428     strDstLevel.Trim();
    429     if(strDstLevel.IsEmpty()) {    //use current dir path as zip file path level 
    430         strDstLevel = strDir;
    431         if(strDstLevel.Right(1) == "/" || strDstLevel.Right(1) == "\")    //remove the last slash
    432             strDstLevel = strDstLevel.Left(strDstLevel.GetLength() - 1);
    433 
    434         int nFind = strDstLevel.ReverseFind('\');    //now get the dst level in zip file
    435         if(nFind == -1) nFind = strDstLevel.ReverseFind('/');
    436         if(nFind != -1) strDstLevel = strDstLevel.Mid(nFind); 
    437     }
    438 
    439     //add pending slash
    440 #ifdef _WIN32
    441     if(strDstLevel.Right(1) != "\") strDstLevel += "\";    
    442 #else
    443     if(strDstLevel.Right(1) != "/") strDstLevel += "/";
    444 #endif
    445 
    446     //remove slash at the beginning of the string
    447     if (strDstLevel.Left(1) == "\" || strDstLevel.Left(1) == "/") 
    448         strDstLevel = strDstLevel.Right(strDstLevel.GetLength() - 1);
    449 
    450     zipFile zf;
    451     zf = zipOpen64(strZipFile, openMode);
    452     if (zf)
    453     {
    454         vector<CStdString> _fileInfo;
    455         GetFilesFromDir(strDir, _fileInfo);
    456         for (size_t i = 0; i < _fileInfo.size(); ++i)
    457         {
    458             CStdString strFilePath = _fileInfo[i];
    459             CStdString strFileLevel;
    460             int nFind = strFilePath.Find(strDir);
    461             if(nFind != -1) strFileLevel = strFilePath.Mid(strlen(strDir));
    462 
    463             if (strFileLevel.Left(1) == "\" || strFileLevel.Left(1) == "/") 
    464                 strFileLevel = strFileLevel.Right(strFileLevel.GetLength() - 1);
    465                 
    466             strFileLevel = strDstLevel + strFileLevel;
    467             strFileLevel.Replace("\", "/");
    468 
    469             DoZipFile(zf, strFilePath.c_str(), strFileLevel.c_str());
    470 //            printf("%s
    %s
    ", strFilePath.c_str(), strFileLevel.c_str());
    471         }
    472         
    473         zipClose(zf, NULL);
    474         return 0;
    475     }
    476     
    477     return __LINE__;
    478 }
    479 
    480 #ifdef _TESTZIP
    481 int main(int argc, char* argv[])
    482 {
    483     if(argc < 2)
    484     {
    485         printf("Usage: %s zipfile filetozip
    ", argv[0]);
    486         getchar();
    487         return 1;
    488     }
    489     const char* szZipFile = argv[1];
    490     bool bFirst = true;
    491     for(int i = 2; i < argc; ++i)
    492     {
    493         const char* filetozip = argv[i];
    494         DWORD dwAttr = GetFileAttributes(filetozip);
    495         if(dwAttr == INVALID_FILE_ATTRIBUTES)
    496         {
    497             printf("invalid file name: %s
    ", filetozip);
    498             continue;
    499         }
    500         if(dwAttr & FILE_ATTRIBUTE_DIRECTORY)
    501         {
    502             DoZipDir(filetozip, "", szZipFile, 
    503                     bFirst ? RG_ZIP_FILE_REPLACE : RG_ZIP_FILE_APPEND);
    504             bFirst = false;
    505         }
    506         else if(dwAttr & FILE_ATTRIBUTE_NORMAL)
    507         {
    508             DoZipFile(filetozip, "", szZipFile, 
    509                     bFirst ? RG_ZIP_FILE_REPLACE : RG_ZIP_FILE_APPEND);
    510             bFirst = false;
    511         }
    512     }
    513 
    514     getchar();
    515 
    516     return 0;
    517 }
    518 
    519 #endif
    View Code

    解压缩API实现,其中的CStdString可以使用CString代替,接口与CString一致。

    其它涉及的代码可以下载minizip或者info-zip,推荐使用minizip,本代码是在minizip的基础上修改而来,支持跨平台

      1 /*
      2 miniunz.c
      3 Version 1.1, February 14h, 2010
      4 sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
      5 
      6 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
      7 
      8 Modifications of Unzip for Zip64
      9 Copyright (C) 2007-2008 Even Rouault
     10 
     11 Modifications for Zip64 support on both zip and unzip
     12 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
     13 */
     14 
     15 #ifndef _WIN32
     16 #ifndef __USE_FILE_OFFSET64
     17 #define __USE_FILE_OFFSET64
     18 #endif
     19 #ifndef __USE_LARGEFILE64
     20 #define __USE_LARGEFILE64
     21 #endif
     22 #ifndef _LARGEFILE64_SOURCE
     23 #define _LARGEFILE64_SOURCE
     24 #endif
     25 #ifndef _FILE_OFFSET_BIT
     26 #define _FILE_OFFSET_BIT 64
     27 #endif
     28 #endif
     29 
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 #include <time.h>
     34 #include <errno.h>
     35 #include <fcntl.h>
     36 
     37 #ifdef _LINUX
     38 #include <unistd.h>
     39 #include <utime.h>
     40 #include <sys/stat.h>
     41 #include <sys/types.h>
     42 #else
     43 #include <direct.h>
     44 #include <io.h>
     45 #include <Windows.h>
     46 #endif
     47 
     48 #include "unzip.h"
     49 #include "stdstring.h"
     50 
     51 #define CASESENSITIVITY (0)
     52 #define WRITEBUFFERSIZE (8192)
     53 #define MAXFILENAME (256)
     54 
     55 /*
     56 #ifdef _WIN32
     57 #define USEWIN32IOAPI
     58 #include "iowin32.h"
     59 #endif
     60 */
     61 /*
     62 mini unzip, demo of unzip package
     63 
     64 usage :
     65 Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
     66 
     67 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
     68 if it exists
     69 */
     70 
     71 
     72 /* change_file_date : change the date/time of a file
     73 filename : the filename of the file where date/time must be modified
     74 dosdate : the new date at the MSDos format (4 bytes)
     75 tmu_date : the SAME new date at the tm_unz format */
     76 static void change_file_date(const char *filename, uLong dosdate, tm_unz tmu_date)
     77 {
     78 #ifdef _WIN32
     79     HANDLE hFile;
     80     FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
     81 
     82     hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
     83         0,NULL,OPEN_EXISTING,0,NULL);
     84     GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
     85     DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
     86     LocalFileTimeToFileTime(&ftLocal,&ftm);
     87     SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
     88     CloseHandle(hFile);
     89 #else
     90 #ifdef _LINUX
     91     struct utimbuf ut;
     92     struct tm newdate;
     93     newdate.tm_sec = tmu_date.tm_sec;
     94     newdate.tm_min=tmu_date.tm_min;
     95     newdate.tm_hour=tmu_date.tm_hour;
     96     newdate.tm_mday=tmu_date.tm_mday;
     97     newdate.tm_mon=tmu_date.tm_mon;
     98     if (tmu_date.tm_year > 1900)
     99         newdate.tm_year=tmu_date.tm_year - 1900;
    100     else
    101         newdate.tm_year=tmu_date.tm_year ;
    102     newdate.tm_isdst=-1;
    103 
    104     ut.actime=ut.modtime=mktime(&newdate);
    105     utime(filename,&ut);
    106 #endif
    107 #endif
    108 }
    109 
    110 
    111 /* mymkdir and change_file_date are not 100 % portable
    112 As I don't know well Unix, I wait feedback for the unix portion */
    113 
    114 static int mymkdir(const char* dirname)
    115 {
    116     int ret=0;
    117 #ifdef _WIN32
    118     ret = _mkdir(dirname);
    119 #else
    120 #ifdef _LINUX
    121     ret = mkdir (dirname,0775);
    122 #endif
    123 #endif
    124     return ret;
    125 }
    126 
    127 int makedir (const char *newdir)
    128 {
    129     char *buffer ;
    130     char *p;
    131     int  len = (int)strlen(newdir);
    132 
    133     if (len <= 0)
    134         return 0;
    135 
    136     buffer = (char*)malloc(len+1);
    137     if (buffer==NULL)
    138     {
    139         printf("Error allocating memory
    ");
    140         return UNZ_INTERNALERROR;
    141     }
    142     strcpy(buffer,newdir);
    143 
    144     if (buffer[len-1] == '/') {
    145         buffer[len-1] = '';
    146     }
    147     if (mymkdir(buffer) == 0)
    148     {
    149         free(buffer);
    150         return 1;
    151     }
    152 
    153     p = buffer+1;
    154     while (1)
    155     {
    156         char hold;
    157 
    158         while(*p && *p != '\' && *p != '/')
    159             p++;
    160         hold = *p;
    161         *p = 0;
    162         if ((mymkdir(buffer) == -1) && (errno == ENOENT))
    163         {
    164             printf("couldn't create directory %s
    ",buffer);
    165             free(buffer);
    166             return 0;
    167         }
    168         if (hold == 0)
    169             break;
    170         *p++ = hold;
    171     }
    172     free(buffer);
    173     return 1;
    174 }
    175 
    176 static int do_extract_currentfile(unzFile uf, const char* password)
    177 {
    178     char filename_inzip[256];
    179     char* filename_withoutpath;
    180     char* p;
    181     int err=UNZ_OK;
    182     FILE *fout=NULL;
    183     void* buf;
    184     uInt size_buf;
    185 
    186     unz_file_info64 file_info;
    187     uLong ratio=0;
    188     err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
    189 
    190     if (err!=UNZ_OK)
    191     {
    192         printf("error %d with zipfile in unzGetCurrentFileInfo
    ",err);
    193         return err;
    194     }
    195 
    196     size_buf = WRITEBUFFERSIZE;
    197     buf = (void*)malloc(size_buf);
    198     if (buf==NULL)
    199     {
    200         printf("Error allocating memory
    ");
    201         return UNZ_INTERNALERROR;
    202     }
    203 
    204     p = filename_withoutpath = filename_inzip;
    205     while ((*p) != '')
    206     {
    207         if (((*p)=='/') || ((*p)=='\'))
    208             filename_withoutpath = p+1;
    209         p++;
    210     }
    211 
    212     if ((*filename_withoutpath)=='')
    213     {
    214         mymkdir(filename_inzip);
    215     }
    216     else
    217     {
    218         const char* write_filename;
    219 
    220         write_filename = filename_inzip;
    221 
    222         err = unzOpenCurrentFilePassword(uf,password);
    223         if (err==UNZ_OK)
    224         {
    225             fout=fopen64(write_filename,"wb");
    226 
    227             /* some zipfile don't contain directory alone before file */
    228             if ((fout==NULL) &&
    229                 (filename_withoutpath!=(char*)filename_inzip))
    230             {
    231                 char c=*(filename_withoutpath-1);
    232                 *(filename_withoutpath-1)='';
    233                 makedir(write_filename);
    234                 *(filename_withoutpath-1)=c;
    235                 fout=fopen64(write_filename,"wb");
    236             }
    237 
    238             if (fout==NULL)
    239             {
    240                 printf("error opening %s
    ",write_filename);
    241             }
    242         }
    243         else
    244         {
    245             printf("error %d with zipfile in unzOpenCurrentFilePassword
    ",err);
    246         }
    247 
    248         if (fout!=NULL)
    249         {
    250             do
    251             {
    252                 err = unzReadCurrentFile(uf,buf,size_buf);
    253                 if (err<0)
    254                 {
    255                     printf("error %d with zipfile in unzReadCurrentFile
    ",err);
    256                     break;
    257                 }
    258                 if (err>0)
    259                     if (fwrite(buf,err,1,fout)!=1)
    260                     {
    261                         printf("error in writing extracted file
    ");
    262                         err=UNZ_ERRNO;
    263                         break;
    264                     }
    265             }
    266             while (err>0);
    267             if (fout)
    268                 fclose(fout);
    269 
    270             if (err==UNZ_OK)
    271                 change_file_date(write_filename,file_info.dosDate,
    272                 file_info.tmu_date);
    273         }
    274 
    275         if (err==UNZ_OK)
    276         {
    277             err = unzCloseCurrentFile (uf);
    278             if (err!=UNZ_OK)
    279             {
    280                 printf("error %d with zipfile in unzCloseCurrentFile
    ",err);
    281             }
    282         }
    283         else
    284             unzCloseCurrentFile(uf); /* don't lose the error */
    285     }
    286 
    287     free(buf);
    288     return err;
    289 }
    290 
    291 
    292 static int do_extract(unzFile uf, const char* password)
    293 {
    294     uLong i;
    295     unz_global_info64 gi;
    296     int err;
    297     FILE* fout=NULL;
    298 
    299     err = unzGetGlobalInfo64(uf,&gi);
    300     if (err!=UNZ_OK)
    301         printf("error %d with zipfile in unzGetGlobalInfo 
    ",err);
    302 
    303     for (i=0;i<gi.number_entry;i++)
    304     {
    305         if (do_extract_currentfile(uf, password) != UNZ_OK)
    306             break;
    307 
    308         if ((i+1) < gi.number_entry)
    309         {
    310             err = unzGoToNextFile(uf);
    311             if (err!=UNZ_OK)
    312             {
    313                 printf("error %d with zipfile in unzGoToNextFile
    ",err);
    314                 break;
    315             }
    316         }
    317     }
    318 
    319     return 0;
    320 }
    321 
    322 static int do_extract_onefile(unzFile uf, const char* filename, const char* password)
    323 {
    324     int err = UNZ_OK;
    325     if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
    326     {
    327         printf("file %s not found in the zipfile
    ",filename);
    328         return 2;
    329     }
    330 
    331     if (do_extract_currentfile(uf, password) == UNZ_OK)
    332         return 0;
    333     else
    334         return 1;
    335 }
    336 
    337 
    338 int DoUnzip(const char* szZipFile, const char* szTargetDir)
    339 {
    340     if (szZipFile == NULL)
    341     {
    342         return __LINE__;
    343     }
    344     
    345     CStdString dirname;
    346     if(szTargetDir) dirname = szTargetDir;
    347     dirname.Trim();
    348 
    349     unzFile uf = unzOpen64(szZipFile);
    350     if (uf)
    351     {
    352 #ifdef _WIN32
    353         if (!dirname.IsEmpty() && _chdir(dirname.c_str()))
    354 #else
    355         if (!dirname.IsEmpty() && chdir(dirname.c_str()))
    356 #endif
    357         {
    358             printf("Error changing into %s, aborting
    ", dirname.c_str());
    359             return __LINE__;
    360         }
    361 
    362         do_extract(uf, NULL);
    363 
    364         unzClose(uf);
    365         return 0;
    366     }
    367     
    368     return __LINE__;
    369 }
    370 
    371 int DoUnzipFile(const char* szZipFile, const char* srcFileToExtract, const char* szTargetDir)
    372 {
    373     if (szZipFile == NULL)
    374     {
    375         return __LINE__;
    376     }
    377 
    378     CStdString dirname;
    379     if(szTargetDir) dirname = szTargetDir;
    380     dirname.Trim();
    381 
    382     unzFile uf = unzOpen64(szZipFile);
    383     if (uf)
    384     {
    385 #ifdef _WIN32
    386         if (!dirname.IsEmpty() && _chdir(dirname.c_str()))
    387 #else
    388         if (!dirname.IsEmpty() && chdir(dirname.c_str()))
    389 #endif
    390         {
    391             printf("Error changing into %s, aborting
    ", dirname.c_str());
    392             return __LINE__;
    393         }
    394 
    395         do_extract_onefile(uf, srcFileToExtract, NULL);
    396 
    397         unzClose(uf);
    398         return 0;
    399     }
    400 
    401     return __LINE__;
    402 }
    403 
    404 #ifdef _TESTUNZIP
    405 int main(int argc, char* argv[])
    406 {
    407     if(argc < 1)
    408     {
    409         printf("Usage: %s zipfile
    ", argv[0]);
    410         return 1;
    411     }
    412 
    413     bool bExtractSingalFile = false;
    414     for(int i = 1; i < argc; ++i)
    415     {
    416         if(strcmp(argv[i], "-s") == 0)
    417         {
    418             if(i + 1 < argc)
    419             {
    420                 i++;
    421                 const char* filetoextract = argv[i];
    422                 printf("extract singal file %s
    ", filetoextract);
    423                 i++;
    424                 if(i < argc)
    425                 {
    426                     DoUnzipFile(argv[i++], filetoextract, NULL);
    427                 }
    428             }
    429         }
    430         else
    431             DoUnzip(argv[i], NULL);
    432     }
    433 
    434     return 0;
    435 }
    436 #endif
    View Code
  • 相关阅读:
    Core Expression
    Linux基础
    express
    C#程序模拟登录批量获取各种邮件内容信息
    Windows Phone 执行模型概述
    Wp8—LongListSelector控件使用
    网页背景图片自然缩放
    Unix sed实用教程系列目录[已完成]
    Unix sed实用教程开篇
    《SpringMVC从入门到放肆》十五、SpringMVC之上传文件
  • 原文地址:https://www.cnblogs.com/jojodru/p/4123797.html
Copyright © 2011-2022 走看看