首页 > 代码库 > 跨平台的zip文件压缩处理,支持压缩解压文件夹

跨平台的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对应压缩文件时的dstLevel21 //其它参数解析同上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 ] = \0;116 117         if (name[len - 1] == /)118             name[len - 1] = \0;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 #else138 uLong filetime(char *f, tm_zip *tmzip, uLong *dt)139 {140     return 0;141 }142 #endif143 #endif144 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     else153         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\n",filenameinzip);219     else220     {221         fin = fopen64(filenameinzip,"rb");222         if (fin==NULL)223         {224             err=ZIP_ERRNO;225             printf("error in opening %s for reading\n",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\n");236             err = ZIP_INTERNALERROR;237         }238         else239         {240             do241             {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\n",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\n",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     else273     {274         err = zipCloseFileInZip(zf);275         if (err!=ZIP_OK)276             printf("error in closing %s in the zipfile\n",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         else293         {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 _WIN32331     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             else356             {357                 _fileInfo.push_back(strFilePath);358             }359         }360         FindClose(hFind);361         return 0;362     }363     364     return __LINE__;365 #else366     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 #endif408 }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         else420         {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 slash432             strDstLevel = strDstLevel.Left(strDstLevel.GetLength() - 1);433 434         int nFind = strDstLevel.ReverseFind(\\);    //now get the dst level in zip file435         if(nFind == -1) nFind = strDstLevel.ReverseFind(/);436         if(nFind != -1) strDstLevel = strDstLevel.Mid(nFind); 437     }438 439     //add pending slash440 #ifdef _WIN32441     if(strDstLevel.Right(1) != "\\") strDstLevel += "\\";    442 #else443     if(strDstLevel.Right(1) != "/") strDstLevel += "/";444 #endif445 446     //remove slash at the beginning of the string447     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\n%s\n", strFilePath.c_str(), strFileLevel.c_str());471         }472         473         zipClose(zf, NULL);474         return 0;475     }476     477     return __LINE__;478 }479 480 #ifdef _TESTZIP481 int main(int argc, char* argv[])482 {483     if(argc < 2)484     {485         printf("Usage: %s zipfile filetozip\n", 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\n", 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     else101         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 #endif107 #endif108 }109 110 111 /* mymkdir and change_file_date are not 100 % portable112 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 _WIN32118     ret = _mkdir(dirname);119 #else120 #ifdef _LINUX121     ret = mkdir (dirname,0775);122 #endif123 #endif124     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\n");140         return UNZ_INTERNALERROR;141     }142     strcpy(buffer,newdir);143 144     if (buffer[len-1] == /) {145         buffer[len-1] = \0;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\n",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\n",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\n");201         return UNZ_INTERNALERROR;202     }203 204     p = filename_withoutpath = filename_inzip;205     while ((*p) != \0)206     {207         if (((*p)==/) || ((*p)==\\))208             filename_withoutpath = p+1;209         p++;210     }211 212     if ((*filename_withoutpath)==\0)213     {214         mymkdir(filename_inzip);215     }216     else217     {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)=\0;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\n",write_filename);241             }242         }243         else244         {245             printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);246         }247 248         if (fout!=NULL)249         {250             do251             {252                 err = unzReadCurrentFile(uf,buf,size_buf);253                 if (err<0)254                 {255                     printf("error %d with zipfile in unzReadCurrentFile\n",err);256                     break;257                 }258                 if (err>0)259                     if (fwrite(buf,err,1,fout)!=1)260                     {261                         printf("error in writing extracted file\n");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\n",err);281             }282         }283         else284             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 \n",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\n",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\n",filename);328         return 2;329     }330 331     if (do_extract_currentfile(uf, password) == UNZ_OK)332         return 0;333     else334         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 _WIN32353         if (!dirname.IsEmpty() && _chdir(dirname.c_str()))354 #else355         if (!dirname.IsEmpty() && chdir(dirname.c_str()))356 #endif357         {358             printf("Error changing into %s, aborting\n", 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 _WIN32386         if (!dirname.IsEmpty() && _chdir(dirname.c_str()))387 #else388         if (!dirname.IsEmpty() && chdir(dirname.c_str()))389 #endif390         {391             printf("Error changing into %s, aborting\n", 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 _TESTUNZIP405 int main(int argc, char* argv[])406 {407     if(argc < 1)408     {409         printf("Usage: %s zipfile\n", 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\n", filetoextract);423                 i++;424                 if(i < argc)425                 {426                     DoUnzipFile(argv[i++], filetoextract, NULL);427                 }428             }429         }430         else431             DoUnzip(argv[i], NULL);432     }433 434     return 0;435 }436 #endif
View Code

 

跨平台的zip文件压缩处理,支持压缩解压文件夹