压缩和解压技术应用很广泛,比如游戏程序中的资源管理器可以使用压缩技术将许多文件打包,便于管理,也节约了空间。本文介绍使用minizip进行解压。由于可以使用zip工具比如winzip,betterzip等进行压缩,所以本文并未涉及压缩。
minizip++
我编写了一个简单的类,与minizip和zlib一起(实际上,Mac OSX中包括了zlib库,但其他平台不一定有zlib库,所以我将其包括在源码中),构成了minizip++。此类仅包含一个类zip::CReader,此类只包括一个函数openFile用于从zip文件中读取一个文件。
范例概述
本示例程序很简单,它从data.zip文件中提取data/hello.txt显示于屏幕上,有兴趣的话,你可以扩展此程序,从zip中提取图像然后显示出来。
废话少说,下面介绍程序:
- 1. 先建立一个View based Xcode项目ziptest,再创建一个目录data,在此目录下建立一个文本文件hello.txt,编辑此文本文件,加入你想在屏幕上显示的内容,比如,我在hello.txt中加入“Hello World!”。压缩data目录,然后将压缩文件data.zip加入Xcode的resource。(注意:此时加入的zip文件将出现在Targets下的“Link Binary With Libraries”下,编译时会出现一个警告,zip文件将不会被加入到.app中。所以你应该将data.zip移动到”Copy Bundle Resources”下)
- 2. ziptestViewController.h部分如下:
1
2
3
4
5@interface ziptestViewController : UIViewController {
UILabel* _mytext;
}
@property (nonatomic,retain) IBOutlet UILabel* _mytext; - 3. 将ziptestViewController.m重命名为ziptestViewController.mm,部分代码如下:
- 4. 双击ziptestViewController.xib打开Interface Builder。添加一个Label。Control+点击File Owner拖动到新建的Label,选取_mytext。
- 5.然后加入header和library搜索路径。比如,我的Header Search Paths为:../../external/minizip++。然后按iphone项目使用静态库的最佳方法一文中介绍的方法加入ziptest项目。
- 6.在viewDidLoad下进入下列代码:
- 6. 按Build and Go运行程序。
1 2 3 4 5 |
minizip++中CReader类中用于解压的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | namespace zip { void CReader::openFile(const std::string& zip,const std::string& file,std::iostream& in) { unzFile uf=NULL; // open zip file #ifdef USEWIN32IOAPI zlib_filefunc_def ffunc; fill_win32_filefunc(&ffunc); uf = unzOpen2(zip.c_str(),&ffunc); #else uf = unzOpen(zip.c_str()); #endif if (uf==NULL) { printf("No zip file found!\n"); return; } // find the file inside zip if ( unzLocateFile(uf,file.c_str(),0) != UNZ_OK ) { printf("%s not found in zip\n",file.c_str()); return; } // file founded,extract it into the stream // open it if ( unzOpenCurrentFile(uf) != UNZ_OK ) { // TODO: error handling printf("unzOpenCurrentFile error\n"); return; } // get the file info char filename_inzip[256]; int err=UNZ_OK; unz_file_info file_info; err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); if (err!=UNZ_OK) { // TODO: error handling printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); return; } // read the file into stream char* buf = (char*)malloc(file_info.uncompressed_size); if ( unzReadCurrentFile(uf,buf,file_info.uncompressed_size) < 0 ) { // TODO: error handling printf("error in unzReadCurrentFile!\n"); free(buf); return; } // write to istream in.rdbuf()->sputn(buf,file_info.uncompressed_size); free(buf); unzCloseCurrentFile(uf); unzClose(uf); } } |
源码下载
注意:编译时,你需要修改头文件路径或者按照我的路径解压源代码。我的路径如下:
root
|—— external
|———– minizip++
|—— test
|———– ziptest



