首页 > 代码库 > 跨平台的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
解压缩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
跨平台的zip文件压缩处理,支持压缩解压文件夹
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。