根据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. #define WRITEBUFFERSIZE (16384)
  67. #define MAXFILENAME (256)
  68.  
  69. #ifdef _WIN32
  70. static uLong filetime(const char *f, tm_zip *tmzip, uLong *dt)
  71. /*char *f; name of file to get info on */
  72. /* tm_zip *tmzip; return value: access, modific. and creation times */
  73. /*uLong *dt; dostime */
  74. {
  75. int ret = ;
  76. {
  77. FILETIME ftLocal;
  78. HANDLE hFind;
  79. WIN32_FIND_DATAA ff32;
  80.  
  81. hFind = FindFirstFileA(f,&ff32);
  82. if (hFind != INVALID_HANDLE_VALUE)
  83. {
  84. FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
  85. FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+,((LPWORD)dt)+);
  86. FindClose(hFind);
  87. ret = ;
  88. }
  89. }
  90. return ret;
  91. }
  92. #else
  93. #ifdef _LINUX
  94. static uLong filetime(const char *f, tm_zip *tmzip, uLong *dt)
  95. /*char *f; name of file to get info on */
  96. /*tm_zip *tmzip; return value: access, modific. and creation times */
  97. /*uLong *dt; dostime */
  98. {
  99. int ret=;
  100. struct stat s; /* results of stat() */
  101. struct tm* filedate;
  102. time_t tm_t=;
  103.  
  104. if (strcmp(f,"-")!=)
  105. {
  106. char name[MAXFILENAME+];
  107. int len = strlen(f);
  108. if (len > MAXFILENAME)
  109. len = MAXFILENAME;
  110.  
  111. strncpy(name, f,MAXFILENAME-);
  112. /* strncpy doesnt append the trailing NULL, of the string is too long. */
  113. name[ MAXFILENAME ] = '\0';
  114.  
  115. if (name[len - ] == '/')
  116. name[len - ] = '\0';
  117. /* not all systems allow stat'ing a file with / appended */
  118. if (stat(name,&s)==)
  119. {
  120. tm_t = s.st_mtime;
  121. ret = ;
  122. }
  123. }
  124. filedate = localtime(&tm_t);
  125.  
  126. tmzip->tm_sec = filedate->tm_sec;
  127. tmzip->tm_min = filedate->tm_min;
  128. tmzip->tm_hour = filedate->tm_hour;
  129. tmzip->tm_mday = filedate->tm_mday;
  130. tmzip->tm_mon = filedate->tm_mon ;
  131. tmzip->tm_year = filedate->tm_year;
  132.  
  133. return ret;
  134. }
  135. #else
  136. uLong filetime(char *f, tm_zip *tmzip, uLong *dt)
  137. {
  138. return ;
  139. }
  140. #endif
  141. #endif
  142.  
  143. static int check_exist_file(const char* filename)
  144. {
  145. FILE* ftestexist;
  146. int ret = ;
  147. ftestexist = fopen64(filename,"rb");
  148. if (ftestexist==NULL)
  149. ret = ;
  150. else
  151. fclose(ftestexist);
  152.  
  153. return ret;
  154. }
  155.  
  156. static int isLargeFile(const char* filename)
  157. {
  158. int largeFile = ;
  159. ZPOS64_T pos = ;
  160. FILE* pFile = fopen64(filename, "rb");
  161.  
  162. if(pFile != NULL)
  163. {
  164. int n = fseeko64(pFile, , SEEK_END);
  165.  
  166. pos = ftello64(pFile);
  167.  
  168. if(pos >= 0xffffffff)
  169. largeFile = ;
  170.  
  171. fclose(pFile);
  172. }
  173.  
  174. return largeFile;
  175. }
  176.  
  177. static int DoZipFile(zipFile zf, const char* srcFile, const char* dstLevel)
  178. {
  179. if(zf == NULL || srcFile == NULL) return __LINE__;
  180.  
  181. int err=;
  182. int size_buf=;
  183. void* buf=NULL;
  184. FILE * fin;
  185. int size_read;
  186. const char* filenameinzip = srcFile;
  187. const char *savefilenameinzip;
  188. zip_fileinfo zi;
  189. int zip64 = ;
  190.  
  191. zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
  192. zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = ;
  193. zi.dosDate = ;
  194. zi.internal_fa = ;
  195. zi.external_fa = ;
  196. filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
  197.  
  198. zip64 = isLargeFile(filenameinzip);
  199.  
  200. /* The path name saved, should not include a leading slash. */
  201. /*if it did, windows/xp and dynazip couldn't read the zip file. */
  202. savefilenameinzip = dstLevel;
  203. while( savefilenameinzip[] == '\\' || savefilenameinzip[] == '/' )
  204. {
  205. savefilenameinzip++;
  206. }
  207.  
  208. err = zipOpenNewFileInZip3_64(zf, savefilenameinzip, &zi,
  209. NULL, , NULL, , NULL /* comment*/,
  210. Z_DEFLATED,
  211. Z_DEFAULT_COMPRESSION,,
  212. -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  213. NULL, , zip64);
  214.  
  215. if (err != ZIP_OK)
  216. printf("error in opening %s in zipfile\n",filenameinzip);
  217. else
  218. {
  219. fin = fopen64(filenameinzip,"rb");
  220. if (fin==NULL)
  221. {
  222. err=ZIP_ERRNO;
  223. printf("error in opening %s for reading\n",filenameinzip);
  224. }
  225. }
  226.  
  227. if (err == ZIP_OK)
  228. {
  229. size_buf = WRITEBUFFERSIZE;
  230. buf = (void*)malloc(size_buf);
  231. if (buf==NULL)
  232. {
  233. printf("Error allocating memory\n");
  234. err = ZIP_INTERNALERROR;
  235. }
  236. else
  237. {
  238. do
  239. {
  240. err = ZIP_OK;
  241. size_read = (int)fread(buf,,size_buf,fin);
  242. if (size_read < size_buf)
  243. if (feof(fin)==)
  244. {
  245. printf("error in reading %s\n",filenameinzip);
  246. err = ZIP_ERRNO;
  247. }
  248.  
  249. if (size_read>)
  250. {
  251. err = zipWriteInFileInZip (zf,buf,size_read);
  252. if (err<)
  253. {
  254. printf("error in writing %s in the zipfile\n",
  255. filenameinzip);
  256. }
  257.  
  258. }
  259. } while ((err == ZIP_OK) && (size_read>));
  260.  
  261. free(buf);
  262. }
  263. }
  264.  
  265. if (fin)
  266. fclose(fin);
  267.  
  268. if (err<)
  269. err=ZIP_ERRNO;
  270. else
  271. {
  272. err = zipCloseFileInZip(zf);
  273. if (err!=ZIP_OK)
  274. printf("error in closing %s in the zipfile\n",
  275. filenameinzip);
  276. }
  277.  
  278. return ;
  279. }
  280.  
  281. int DoZipFile(const char* strFile, const char* dstLevel, const char* strZipFile, int replaceFlag)
  282. {
  283. int openMode = APPEND_STATUS_CREATE;
  284. if (check_exist_file(strZipFile))
  285. {
  286. if (replaceFlag == RG_ZIP_FILE_APPEND)
  287. {
  288. openMode = APPEND_STATUS_ADDINZIP;
  289. }
  290. else
  291. {
  292. openMode = APPEND_STATUS_CREATE;
  293. }
  294. }
  295.  
  296. zipFile zf;
  297. zf = zipOpen64(strZipFile, openMode);
  298. if (zf)
  299. {
  300. CStdString strDstLevel;
  301. if(dstLevel) strDstLevel = dstLevel;
  302. strDstLevel.Trim();
  303. if(strDstLevel.IsEmpty())
  304. {
  305. strDstLevel = strFile;
  306. if(strDstLevel.Right() == "\\" || strDstLevel.Right() == "/")
  307. strDstLevel = strDstLevel.Left(strDstLevel.GetLength() - );
  308. int nFind = strDstLevel.ReverseFind('\\');
  309. if(nFind == -) nFind = strDstLevel.ReverseFind('/');
  310. if(nFind != -)
  311. strDstLevel = strDstLevel.Mid(nFind);
  312. }
  313.  
  314. if (strDstLevel.Left() == "\\" || strDstLevel.Left() == "/")
  315. strDstLevel = strDstLevel.Right(strDstLevel.GetLength() - );
  316.  
  317. DoZipFile(zf, strFile, strDstLevel.c_str());
  318. zipClose(zf, NULL);
  319. return ;
  320. }
  321.  
  322. return ;
  323. }
  324.  
  325. static int GetFilesFromDir(const char* strDir, vector<CStdString> &_fileInfo)
  326. {
  327.  
  328. #ifdef _WIN32
  329. CStdString strFind = strDir;
  330. CStdString strPath;
  331. if (strFind.Right() != "\\")
  332. {
  333. strFind += "\\";
  334. }
  335. strPath = strFind;
  336. strFind += "*.*";
  337.  
  338. WIN32_FIND_DATA wfd;
  339. HANDLE hFind = FindFirstFile(strFind, &wfd);
  340. if (hFind != INVALID_HANDLE_VALUE)
  341. {
  342. while(FindNextFile(hFind, &wfd))
  343. {
  344. if (strcmp(wfd.cFileName, ".") == || strcmp(wfd.cFileName, "..") == )
  345. {
  346. continue;
  347. }
  348. CStdString strFilePath = strPath + wfd.cFileName;
  349. if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  350. {
  351. GetFilesFromDir(strFilePath.c_str(), _fileInfo);
  352. }
  353. else
  354. {
  355. _fileInfo.push_back(strFilePath);
  356. }
  357. }
  358. FindClose(hFind);
  359. return ;
  360. }
  361.  
  362. return __LINE__;
  363. #else
  364. struct stat statbuf;
  365. struct dirent *dirp;
  366. DIR *dp;
  367. const char* szPath = strDir;
  368.  
  369. if(lstat(szPath, &statbuf) < )
  370. {
  371. perror("lstat");
  372. return __LINE__;
  373. }
  374. if(S_ISDIR(statbuf.st_mode) == )
  375. {
  376. _fileInfo.push_back(szPath);
  377. return ;
  378. }
  379.  
  380. if((dp = opendir(szPath)) == NULL)
  381. {
  382. perror("opendir");
  383. return __LINE__;
  384. }
  385.  
  386. while((dirp = readdir(dp)) != NULL)
  387. {
  388. if(strcmp(dirp->d_name, ".") == ||
  389. strcmp(dirp->d_name, "..") == )
  390. continue;
  391.  
  392. std::string subDir = string(szPath) + "/";
  393. subDir += dirp->d_name;
  394. if(dirp->d_type == DT_REG)
  395. {
  396. _fileInfo.push_back(subDir);
  397. }
  398. else if(dirp->d_type == DT_DIR)
  399. {
  400. GetFilesFromDir(subDir.c_str(), _fileInfo);
  401. }
  402. }
  403.  
  404. closedir(dp);
  405. #endif
  406. }
  407.  
  408. int DoZipDir(const char* strDir, const char* dstLevel, const char* strZipFile, int replaceFlag)
  409. {
  410. int openMode = APPEND_STATUS_CREATE;
  411. if(check_exist_file(strZipFile))
  412. {
  413. if (replaceFlag == RG_ZIP_FILE_APPEND)
  414. {
  415. openMode = APPEND_STATUS_ADDINZIP;
  416. }
  417. else
  418. {
  419. remove(strZipFile);
  420. openMode = APPEND_STATUS_CREATE;
  421. }
  422. }
  423.  
  424. CStdString strDstLevel;
  425. if(dstLevel) strDstLevel= dstLevel;
  426. strDstLevel.Trim();
  427. if(strDstLevel.IsEmpty()) { //use current dir path as zip file path level
  428. strDstLevel = strDir;
  429. if(strDstLevel.Right() == "/" || strDstLevel.Right() == "\\") //remove the last slash
  430. strDstLevel = strDstLevel.Left(strDstLevel.GetLength() - );
  431.  
  432. int nFind = strDstLevel.ReverseFind('\\'); //now get the dst level in zip file
  433. if(nFind == -) nFind = strDstLevel.ReverseFind('/');
  434. if(nFind != -) strDstLevel = strDstLevel.Mid(nFind);
  435. }
  436.  
  437. //add pending slash
  438. #ifdef _WIN32
  439. if(strDstLevel.Right() != "\\") strDstLevel += "\\";
  440. #else
  441. if(strDstLevel.Right() != "/") strDstLevel += "/";
  442. #endif
  443.  
  444. //remove slash at the beginning of the string
  445. if (strDstLevel.Left() == "\\" || strDstLevel.Left() == "/")
  446. strDstLevel = strDstLevel.Right(strDstLevel.GetLength() - );
  447.  
  448. zipFile zf;
  449. zf = zipOpen64(strZipFile, openMode);
  450. if (zf)
  451. {
  452. vector<CStdString> _fileInfo;
  453. GetFilesFromDir(strDir, _fileInfo);
  454. for (size_t i = ; i < _fileInfo.size(); ++i)
  455. {
  456. CStdString strFilePath = _fileInfo[i];
  457. CStdString strFileLevel;
  458. int nFind = strFilePath.Find(strDir);
  459. if(nFind != -) strFileLevel = strFilePath.Mid(strlen(strDir));
  460.  
  461. if (strFileLevel.Left() == "\\" || strFileLevel.Left() == "/")
  462. strFileLevel = strFileLevel.Right(strFileLevel.GetLength() - );
  463.  
  464. strFileLevel = strDstLevel + strFileLevel;
  465. strFileLevel.Replace("\\", "/");
  466.  
  467. DoZipFile(zf, strFilePath.c_str(), strFileLevel.c_str());
  468. // printf("%s\n%s\n", strFilePath.c_str(), strFileLevel.c_str());
  469. }
  470.  
  471. zipClose(zf, NULL);
  472. return ;
  473. }
  474.  
  475. return __LINE__;
  476. }
  477.  
  478. #ifdef _TESTZIP
  479. int main(int argc, char* argv[])
  480. {
  481. if(argc < )
  482. {
  483. printf("Usage: %s zipfile filetozip\n", argv[]);
  484. getchar();
  485. return ;
  486. }
  487. const char* szZipFile = argv[];
  488. bool bFirst = true;
  489. for(int i = ; i < argc; ++i)
  490. {
  491. const char* filetozip = argv[i];
  492. DWORD dwAttr = GetFileAttributes(filetozip);
  493. if(dwAttr == INVALID_FILE_ATTRIBUTES)
  494. {
  495. printf("invalid file name: %s\n", filetozip);
  496. continue;
  497. }
  498. if(dwAttr & FILE_ATTRIBUTE_DIRECTORY)
  499. {
  500. DoZipDir(filetozip, "", szZipFile,
  501. bFirst ? RG_ZIP_FILE_REPLACE : RG_ZIP_FILE_APPEND);
  502. bFirst = false;
  503. }
  504. else if(dwAttr & FILE_ATTRIBUTE_NORMAL)
  505. {
  506. DoZipFile(filetozip, "", szZipFile,
  507. bFirst ? RG_ZIP_FILE_REPLACE : RG_ZIP_FILE_APPEND);
  508. bFirst = false;
  509. }
  510. }
  511.  
  512. getchar();
  513.  
  514. return ;
  515. }
  516.  
  517. #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. /* change_file_date : change the date/time of a file
  72. filename : the filename of the file where date/time must be modified
  73. dosdate : the new date at the MSDos format (4 bytes)
  74. tmu_date : the SAME new date at the tm_unz format */
  75. static void change_file_date(const char *filename, uLong dosdate, tm_unz tmu_date)
  76. {
  77. #ifdef _WIN32
  78. HANDLE hFile;
  79. FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
  80.  
  81. hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
  82. ,NULL,OPEN_EXISTING,,NULL);
  83. GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
  84. DosDateTimeToFileTime((WORD)(dosdate>>),(WORD)dosdate,&ftLocal);
  85. LocalFileTimeToFileTime(&ftLocal,&ftm);
  86. SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
  87. CloseHandle(hFile);
  88. #else
  89. #ifdef _LINUX
  90. struct utimbuf ut;
  91. struct tm newdate;
  92. newdate.tm_sec = tmu_date.tm_sec;
  93. newdate.tm_min=tmu_date.tm_min;
  94. newdate.tm_hour=tmu_date.tm_hour;
  95. newdate.tm_mday=tmu_date.tm_mday;
  96. newdate.tm_mon=tmu_date.tm_mon;
  97. if (tmu_date.tm_year > )
  98. newdate.tm_year=tmu_date.tm_year - ;
  99. else
  100. newdate.tm_year=tmu_date.tm_year ;
  101. newdate.tm_isdst=-;
  102.  
  103. ut.actime=ut.modtime=mktime(&newdate);
  104. utime(filename,&ut);
  105. #endif
  106. #endif
  107. }
  108.  
  109. /* mymkdir and change_file_date are not 100 % portable
  110. As I don't know well Unix, I wait feedback for the unix portion */
  111.  
  112. static int mymkdir(const char* dirname)
  113. {
  114. int ret=;
  115. #ifdef _WIN32
  116. ret = _mkdir(dirname);
  117. #else
  118. #ifdef _LINUX
  119. ret = mkdir (dirname,);
  120. #endif
  121. #endif
  122. return ret;
  123. }
  124.  
  125. int makedir (const char *newdir)
  126. {
  127. char *buffer ;
  128. char *p;
  129. int len = (int)strlen(newdir);
  130.  
  131. if (len <= )
  132. return ;
  133.  
  134. buffer = (char*)malloc(len+);
  135. if (buffer==NULL)
  136. {
  137. printf("Error allocating memory\n");
  138. return UNZ_INTERNALERROR;
  139. }
  140. strcpy(buffer,newdir);
  141.  
  142. if (buffer[len-] == '/') {
  143. buffer[len-] = '\0';
  144. }
  145. if (mymkdir(buffer) == )
  146. {
  147. free(buffer);
  148. return ;
  149. }
  150.  
  151. p = buffer+;
  152. while ()
  153. {
  154. char hold;
  155.  
  156. while(*p && *p != '\\' && *p != '/')
  157. p++;
  158. hold = *p;
  159. *p = ;
  160. if ((mymkdir(buffer) == -) && (errno == ENOENT))
  161. {
  162. printf("couldn't create directory %s\n",buffer);
  163. free(buffer);
  164. return ;
  165. }
  166. if (hold == )
  167. break;
  168. *p++ = hold;
  169. }
  170. free(buffer);
  171. return ;
  172. }
  173.  
  174. static int do_extract_currentfile(unzFile uf, const char* password)
  175. {
  176. char filename_inzip[];
  177. char* filename_withoutpath;
  178. char* p;
  179. int err=UNZ_OK;
  180. FILE *fout=NULL;
  181. void* buf;
  182. uInt size_buf;
  183.  
  184. unz_file_info64 file_info;
  185. uLong ratio=;
  186. err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,,NULL,);
  187.  
  188. if (err!=UNZ_OK)
  189. {
  190. printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
  191. return err;
  192. }
  193.  
  194. size_buf = WRITEBUFFERSIZE;
  195. buf = (void*)malloc(size_buf);
  196. if (buf==NULL)
  197. {
  198. printf("Error allocating memory\n");
  199. return UNZ_INTERNALERROR;
  200. }
  201.  
  202. p = filename_withoutpath = filename_inzip;
  203. while ((*p) != '\0')
  204. {
  205. if (((*p)=='/') || ((*p)=='\\'))
  206. filename_withoutpath = p+;
  207. p++;
  208. }
  209.  
  210. if ((*filename_withoutpath)=='\0')
  211. {
  212. mymkdir(filename_inzip);
  213. }
  214. else
  215. {
  216. const char* write_filename;
  217.  
  218. write_filename = filename_inzip;
  219.  
  220. err = unzOpenCurrentFilePassword(uf,password);
  221. if (err==UNZ_OK)
  222. {
  223. fout=fopen64(write_filename,"wb");
  224.  
  225. /* some zipfile don't contain directory alone before file */
  226. if ((fout==NULL) &&
  227. (filename_withoutpath!=(char*)filename_inzip))
  228. {
  229. char c=*(filename_withoutpath-);
  230. *(filename_withoutpath-)='\0';
  231. makedir(write_filename);
  232. *(filename_withoutpath-)=c;
  233. fout=fopen64(write_filename,"wb");
  234. }
  235.  
  236. if (fout==NULL)
  237. {
  238. printf("error opening %s\n",write_filename);
  239. }
  240. }
  241. else
  242. {
  243. printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
  244. }
  245.  
  246. if (fout!=NULL)
  247. {
  248. do
  249. {
  250. err = unzReadCurrentFile(uf,buf,size_buf);
  251. if (err<)
  252. {
  253. printf("error %d with zipfile in unzReadCurrentFile\n",err);
  254. break;
  255. }
  256. if (err>)
  257. if (fwrite(buf,err,,fout)!=)
  258. {
  259. printf("error in writing extracted file\n");
  260. err=UNZ_ERRNO;
  261. break;
  262. }
  263. }
  264. while (err>);
  265. if (fout)
  266. fclose(fout);
  267.  
  268. if (err==UNZ_OK)
  269. change_file_date(write_filename,file_info.dosDate,
  270. file_info.tmu_date);
  271. }
  272.  
  273. if (err==UNZ_OK)
  274. {
  275. err = unzCloseCurrentFile (uf);
  276. if (err!=UNZ_OK)
  277. {
  278. printf("error %d with zipfile in unzCloseCurrentFile\n",err);
  279. }
  280. }
  281. else
  282. unzCloseCurrentFile(uf); /* don't lose the error */
  283. }
  284.  
  285. free(buf);
  286. return err;
  287. }
  288.  
  289. static int do_extract(unzFile uf, const char* password)
  290. {
  291. uLong i;
  292. unz_global_info64 gi;
  293. int err;
  294. FILE* fout=NULL;
  295.  
  296. err = unzGetGlobalInfo64(uf,&gi);
  297. if (err!=UNZ_OK)
  298. printf("error %d with zipfile in unzGetGlobalInfo \n",err);
  299.  
  300. for (i=;i<gi.number_entry;i++)
  301. {
  302. if (do_extract_currentfile(uf, password) != UNZ_OK)
  303. break;
  304.  
  305. if ((i+) < gi.number_entry)
  306. {
  307. err = unzGoToNextFile(uf);
  308. if (err!=UNZ_OK)
  309. {
  310. printf("error %d with zipfile in unzGoToNextFile\n",err);
  311. break;
  312. }
  313. }
  314. }
  315.  
  316. return ;
  317. }
  318.  
  319. static int do_extract_onefile(unzFile uf, const char* filename, const char* password)
  320. {
  321. int err = UNZ_OK;
  322. if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
  323. {
  324. printf("file %s not found in the zipfile\n",filename);
  325. return ;
  326. }
  327.  
  328. if (do_extract_currentfile(uf, password) == UNZ_OK)
  329. return ;
  330. else
  331. return ;
  332. }
  333.  
  334. int DoUnzip(const char* szZipFile, const char* szTargetDir)
  335. {
  336. if (szZipFile == NULL)
  337. {
  338. return __LINE__;
  339. }
  340.  
  341. CStdString dirname;
  342. if(szTargetDir) dirname = szTargetDir;
  343. dirname.Trim();
  344.  
  345. unzFile uf = unzOpen64(szZipFile);
  346. if (uf)
  347. {
  348. #ifdef _WIN32
  349. if (!dirname.IsEmpty() && _chdir(dirname.c_str()))
  350. #else
  351. if (!dirname.IsEmpty() && chdir(dirname.c_str()))
  352. #endif
  353. {
  354. printf("Error changing into %s, aborting\n", dirname.c_str());
  355. return __LINE__;
  356. }
  357.  
  358. do_extract(uf, NULL);
  359.  
  360. unzClose(uf);
  361. return ;
  362. }
  363.  
  364. return __LINE__;
  365. }
  366.  
  367. int DoUnzipFile(const char* szZipFile, const char* srcFileToExtract, const char* szTargetDir)
  368. {
  369. if (szZipFile == NULL)
  370. {
  371. return __LINE__;
  372. }
  373.  
  374. CStdString dirname;
  375. if(szTargetDir) dirname = szTargetDir;
  376. dirname.Trim();
  377.  
  378. unzFile uf = unzOpen64(szZipFile);
  379. if (uf)
  380. {
  381. #ifdef _WIN32
  382. if (!dirname.IsEmpty() && _chdir(dirname.c_str()))
  383. #else
  384. if (!dirname.IsEmpty() && chdir(dirname.c_str()))
  385. #endif
  386. {
  387. printf("Error changing into %s, aborting\n", dirname.c_str());
  388. return __LINE__;
  389. }
  390.  
  391. do_extract_onefile(uf, srcFileToExtract, NULL);
  392.  
  393. unzClose(uf);
  394. return ;
  395. }
  396.  
  397. return __LINE__;
  398. }
  399.  
  400. #ifdef _TESTUNZIP
  401. int main(int argc, char* argv[])
  402. {
  403. if(argc < )
  404. {
  405. printf("Usage: %s zipfile\n", argv[]);
  406. return ;
  407. }
  408.  
  409. bool bExtractSingalFile = false;
  410. for(int i = ; i < argc; ++i)
  411. {
  412. if(strcmp(argv[i], "-s") == )
  413. {
  414. if(i + < argc)
  415. {
  416. i++;
  417. const char* filetoextract = argv[i];
  418. printf("extract singal file %s\n", filetoextract);
  419. i++;
  420. if(i < argc)
  421. {
  422. DoUnzipFile(argv[i++], filetoextract, NULL);
  423. }
  424. }
  425. }
  426. else
  427. DoUnzip(argv[i], NULL);
  428. }
  429.  
  430. return ;
  431. }
  432. #endif

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

  1. Linux命令(16)压缩,解压文件

    tar: 简介:tar命令只是把目录打包成一个归档(文件),并不负责压缩.在tar命令中可以带参数调用gzip或bzip2压缩.因为gzip和bzip2只能压缩单个文件. 在linux下是不需要后缀名 ...

  2. 关于Java解压文件的一些坑及经验分享(MALFORMED异常)

    文章也已经同步到我的csdn博客: http://blog.csdn.net/u012881584/article/details/72615481 关于Java解压文件的一些坑及经验分享 就在本周, ...

  3. java批量解压文件夹下的所有压缩文件(.rar、.zip、.gz、.tar.gz)

    // java批量解压文件夹下的所有压缩文件(.rar..zip..gz..tar.gz) 新建工具类: package com.mobile.utils; import com.github.jun ...

  4. .NET使用ICSharpCode.SharpZipLib压缩/解压文件

    SharpZipLib是国外开源加压解压库,可以方便的对文件进行加压/解压 1.下载ICSharpCode.SharpZipLib.dll,并复制到bin目录下 http://www.icsharpc ...

  5. SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html

    SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html 说明: 1.环境:SpringMVC+Spring+Tomcat7+JDK1.7 2.支持 zip和rar格式的压 ...

  6. 【转载】.NET压缩/解压文件/夹组件

    转自:http://www.cnblogs.com/asxinyu/archive/2013/03/05/2943696.html 阅读目录 1.前言 2.关于压缩格式和算法的基础 3.几种常见的.N ...

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

    linux(ubuntu)文件解压及压缩文件 ubuntu支持文件的解压及压缩功能, 如果ubuntu上面没有安装过unzip工具的话,可以通过下面命令安装: sudo apt-get install ...

  8. C# 压缩、解压文件夹或文件(带密码)

    今天梳理一下项目中用到的压缩.解压文件夹或文件的方法,发现因为需求不同,已经用了好几个不同组件.今天就好好整理记录下,别下次遇到需求又重头开始了. DotNetZip DotNetZip是一个开源的免 ...

  9. Unity3D研究院之LZMA压缩文件与解压文件

    原地址:http://www.xuanyusong.com/archives/3095 前两天有朋友告诉我Unity的Assetbundle是LZMA压缩的,刚好今天有时间那么就研究研究LZMA.它是 ...

  10. AIX系统上压缩与解压文件

    压缩. 命令格式: #tar -cvf (或xvf)+文件名+设备 C:是本地到其他设备 x:是其他设备到本地 r:是追加,比如打包时,将其他文件追加进来使用该参数. t:显示tar包里的内容,但还原 ...

随机推荐

  1. SQL第二课-创建数据表

    查看有多少数据库 SHOW DATABASES; 进入数据库:USE <数据库名> 举例:USE test;//进入test数据库 查看当前进入的是哪个数据库 SELECT DATABAS ...

  2. 如何vs升级后10和12都能同时兼容

    如图: 项目2008解决方案sln文件升级2012后,都能同时使用. 升级办法:先复制vs2008版本的解决方案文件.升级2012后,再将文件复制到目录里面即可.注意升级过程中产生的升级文件(Upgr ...

  3. BAE、SAE 与 GAE 对比

    从数据库.应用配置.计费.域名绑定.平台服务对比了 BAE.SAE 以及 GAE 的优劣,最后给出云平台选型的建议. 数据库SAE 不支持 InnoDB(可申请支持),BAE 默认支持. BAE 不支 ...

  4. docker-compose.yml 语法说明

    YAML 模板文件语法 默认的模板文件是 docker-compose.yml,其中定义的每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)来自动构建. 其 ...

  5. ReentrantLock与synchronized的差别

    总的来说,lock更加灵活. 主要同样点:Lock能完毕synchronized所实现的全部功能 不同: 1.ReentrantLock功能性方面更全面,比方时间锁等候,可中断锁等候,锁投票等,因此更 ...

  6. thinkphp实现短信验证注册

    前言 注册时经常需要用到短信验证码,本文记录一下思路和具体实现. 短信验证平台使用云片,短信验证码的生成使用thinkphp. 思路 1.用户输入手机号,请求获取短信验证码. 2.thinkphp生成 ...

  7. 简单回顾C++中的字符串

    C++中有两种字符串形式,一种是C语言字符数组,一般可以使用 char*指针来操作它:另一种是C++中基于标准库的string类型,这算是更高层次的抽象数据类型. 主要讨论一下string类型,既然是 ...

  8. eclipse4.3 kepler中安装maven

    1.软件准备 a:Eclipse 4.3 http://www.eclipse.org/downloads/ b:maven http://maven.apache.org/download.cgi ...

  9. js 的post提交的写法

    function AddEditDevice(data){ var form = $("#deviceEditform"); if (form.length == 0) { for ...

  10. 23、Javascript DOM

    DOM Document Object Model(文档对象模型)定义了html和xml的文档标准. DOM 节点树 <html> <head> <title>DO ...