跨平台的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 ] = ‘\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 #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\n",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\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         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\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     else
273     {
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         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\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 _TESTZIP
481 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

解压缩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\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     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)=‘\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         else
244         {
245             printf("error %d with zipfile in unzOpenCurrentFilePassword\n",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\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         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 \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     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\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 _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\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 _TESTUNZIP
405 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         else
431             DoUnzip(argv[i], NULL);
432     }
433
434     return 0;
435 }
436 #endif

时间: 2024-10-11 16:13:54

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

使用 ICSharpCode.SharpZipLib.Zip压缩解压文件

/// <summary> /// 功能:解压zip格式的文件. /// </summary> /// <param name="zipFilePath">压缩文件路径</param> /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param> /// <returns>解压是否成功</ret

本地上传文件至服务器的技巧(linux文件压缩及解压文件)

linux(ubuntu)文件解压及压缩文件 ubuntu支持文件的解压及压缩功能, 如果ubuntu上面没有安装过unzip工具的话,可以通过下面命令安装: sudo apt-get install unzip zip压缩文件夹,文件及解压文件的命令 1.压缩文件夹 zip -r 目标文件名.zip 要压缩的文件夹 2.把文件 unzip 文件 目的地 把/home目录下面的mydata.zip解压到mydatabak目录里面 3.把文件解压到当前目录 unzip 要解压的文件 其他的详细请查

【转】用ZipArchive在App里压缩、解压文件

在这篇教程里,我将演示如何在iOS应用内压缩和解压文件.我们会使用到一个叫做ZipArchive的第三方库来实现这一功能.虽然还有其他压缩和解压文件的方案,但我感觉ZipArchive是最快和最易使用的. 为什么我需要解压文件? 这个问题很好.有很多理由可以用来解释为什么你的应用需要支持压缩和解压文件,这是其中一些: 苹果的50M下载限制 苹果强制要求通过3G网络下载的应用大小不能超过50M,绕过这个限制的方法是尽量让你的二进制包足够小,然后在应用里下载需要的资源,当然最好的方式是先把资源打包成

通过SharpZipLib来压缩解压文件

在项目开发中,一些比较常用的功能就是压缩解压文件了,其实类似的方法有许多 ,现将通过第三方类库SharpZipLib来压缩解压文件的方法介绍如下,主要目的是方便以后自己阅读,当然可以帮到有需要的朋友更好了,代码比较简单. public class ZipAndUnzipFileBySharpZipLib    {        /// <summary>        /// 解压文件        /// </summary>        /// <param name=

(转)使用 linux tar 命令压缩与解压文件

原文链接 http://www.cnblogs.com/qq78292959/archive/2011/07/06/2099427.html tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的参数是根据需要在压缩或解压档案时可选的. -z:有gzip属性的-j:有bz2属性的-Z:有compress属性的-v:显示所有过程-O:将文件解开到标准输出

C#工具类:使用SharpZipLib进行压缩、解压文件

SharpZipLib是一个开源的C#压缩解压库,应用非常广泛.就像用ADO.NET操作数据库要打开连接.执行命令.关闭连接等多个步骤一样,用SharpZipLib进行压缩和解压也需要多个步骤.SharpZipLib功能比较强大,在很多C#的应用中,都有它的身影,我们可以通过引入SharpZipLib类库文件,在程序中实现自动压缩文件以及解压缩文件的功能,例如一个常见的情景就是用户客户端程序下载更新包,下载完成之后,在本地自动解压文件. SharpZipLib的官方地址是:http://icsh

Linux tar (打包.压缩.解压缩)命令说明 | tar如何解压文件到指定的目录?

打包举例:将 /usr/local/src/zlib-1.2.5目录下的文件打包成 zlib-1.2.5.tar.gz cd /usr/local/src tar -czvf ./zlib-1.2.5.tar.gz ./zlib-1.2.5/* # 压缩到制定目录下(如:/root/2/ ) tar -czvf /root/2/zlib-1.2.5.tar.gz ./zlib-1.2.5/* #压缩 tar  -czvf   ***.tar.gz tar  -cjvf   ***.tar.bz2

5、分区格式化、压缩、挂载、解压 学习笔记

文件系统: MBR: Master Boot Record, 主引导记录(512bytes存在第0扇区) 512bytes: bootloader: 446bytes fat: 64bytes, 16bytes, 4 MBR有效性标记:5A 至多4主分区,可以3主分区1扩展分区(扩展分区引用额外的分区表),要使用扩展分区需在扩展分区中再另行划分逻辑分区 硬盘接口: IDE(ATA).SCSI.SATA(6Gbps).SAS(6Gbps) fdisk /dev/sda d: 删除 l: 列出内核支

Java的压缩、解压及压缩加密、解密解压 例子

为了节约带宽.加快传送速度,http协议支持gzip的压缩,但如果我们的app与后台不是通过http协议通讯的,那么压缩.解压这个流程需要自己写.下面给出compress和decompress的代码: public static byte[] compress(byte[] data) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 压缩 GZIPOutputStream gos =