[C/C++]_[初级]_[使用zlib库压缩文件](一)

2014-11-24 13:26:19 · 作者: · 浏览: 71


场景:

1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言。

2. zlib比较常用,编译也方便,使用它来做压缩吧。MacOSX平台默认支持zlib库.

http://zlib.net

3. zlib库里的 src\contrib\minizip\minizip.c 里有压缩例子, 我现在使用的是zlib 1.2.5,用vs2010编译完。下载地址:

http://download.csdn.net/detail/infoworld/8177625

4. 自己封装了一下ZipHelper便于使用,首先先得编译zlib为dll版本, 这个类就是删减了minizip.c的一些东西, 支持中文路径,项目需要目前只支持一级目录,如果有子目录的也不难,自己改改吧。

5. 使用方式, 注意, 路径字符串必须是utf8格式编码, 编译时要加上预编译宏 ZLIB_WINAPI

ZipHelper z;
z.AddFile(utf8_path1);
z.AddFile(utf8_path2);
z.ToZip(utf8_output_zip_path);

 6. MacOSX没测过,理论上应该可以编译过。 
 

zip_helper.h

#ifndef __ZIP_HELPER
#define __ZIP_HELPER

#include 
  
   
#include 
   
     //1.暂时不支持子目录 //注意: 因为使用了zlib库,使用时加上预编译宏 ZLIB_WINAPI class ZipHelper { public: ZipHelper(){} ~ZipHelper(){} //path: utf8 path ZipHelper& AddFile(const char* input_path); //output_path :utf8 path bool ToZip(const char* output_path); private: std::vector
    
      files_; }; #endif
    
   
  

zip_helper.cpp

#include "zip_helper.h"


#ifndef _WIN32
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include "zlib.h" #include "zip.h" #ifdef _WIN32 #define USEWIN32IOAPI #include "iowin32.h" #endif #define WRITEBUFFERSIZE (16384) #define MAXFILENAME (256) #ifdef _WIN32 static wchar_t* QXUtf82Unicode(const char* utf) { if(!utf || !strlen(utf)) { return NULL; } int dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,utf,-1,NULL,0); size_t num = dwUnicodeLen*sizeof(wchar_t); wchar_t *pwText = (wchar_t*)malloc(num); memset(pwText,0,num); MultiByteToWideChar(CP_UTF8,0,utf,-1,pwText,dwUnicodeLen); return pwText; } static FILE* ZipFopen(const char* path,const char* mode) { wchar_t* path_u = QXUtf82Unicode(path); wchar_t* mode_u = QXUtf82Unicode(mode); FILE* file = _wfopen(path_u,mode_u); free(path_u); free(mode_u); return file; } /* name of file to get info on */ /* return value: access, modific. and creation times */ /* 
          dostime */ uLong filetime(const char* f, tm_zip *tmzip, uLong *dt) { int ret = 0; { FILETIME ftLocal; HANDLE hFind; WIN32_FIND_DATA ff32; wchar_t *unicode = QXUtf82Unicode(f); hFind = FindFirstFile(unicode,&ff32); if (hFind != INVALID_HANDLE_VALUE) { FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); FindClose(hFind); ret = 1; } free(unicode); } return ret; } #else #define ZipFopen fopen; #endif ZipHelper& ZipHelper::AddFile(const char* input_path) { files_.push_back(input_path); return *this; } bool ZipHelper::ToZip(const char* output_path) { int err=0; zipFile zf; int errclose; int opt_compress_level = Z_DEFAULT_COMPRESSION; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc; fill_win32_filefunc64W(&ffunc); wchar_t* temp_path = QXUtf82Unicode(output_path); zf = zipOpen2_64(temp_path,APPEND_STATUS_CREATE,NULL,&ffunc); free(temp_path); #else zf = zipOpen64(output_path,APPEND_STATUS_CREATE); #endif if (zf == NULL) { printf("error opening %s\n",output_path); err= ZIP_ERRNO; return false; } int size = files_.size(); void* buf = NULL; int size_buf = WRITEBUFFERSIZE; buf = (void*)malloc(siz