iOS中使用ZipArchive 壓縮和解壓縮文件


引自 http://www.36duo.com/thread-119-1-1.html

在本教程中,我將演示如何在iOS程序中壓縮和解壓縮文件。我們將使用一個叫做ZipArchive的第三方庫來實現。盡管壓縮和解壓縮有許多其他的方案可選,但是我覺得ZipArchive庫是最快捷、最簡單的解決方案。let’s go

為什么我需要解壓縮文件

有許多原因能解釋為什么我要在工程中使用壓縮和解壓縮功能,下面是幾個常見的原因:

蘋果App Store的50M下載限制

蘋 果公司出於流量的考慮,規定在非WIFI環境下,限制用戶只能下載小於50M的應用或游戲。這樣一來,對於一些數據或數據包較大的應用,我們只能盡量減小 應用二進制包的體積。而把數據打包到zip中,這樣App可以通過網絡下載數據包,解壓出所需要的內容,而且這樣也可以動態的更新內容

動態更新內容

這 一點在上面已經提過了。如果應用所需要的資源需要動態更新,一種常見的做法是更新資源,重新打包,重新提交到App store,這樣做你需要等待漫長的審核、上架時間。一般情況下是一周左右的時間。更好的方法是將這些資源打包放置在服務器上,App從服務器(或者雲存 儲)上下載,然后解壓。這樣做的好處顯而易見,那就是可以快速更新,動態更新,不需要重新打包、上傳、審核,省時省力。

從Web上下載zip文件

Safari和郵件程序都不支持zip的查看,通過ZipArchive你就可以為你的設備增加查看zip文件的能力了,盡管App Store里已經有一些App支持這些功能了

工程設置

首先從google code上check out一份代碼,svn地址是:http://ziparchive.googlecode.com/svn/trunk/ziparchive-read-only

在終端中輸入如下命令即可check out了:

svn co http://ziparchive.googlecode.com/svn/trunk/ziparchive-read-only

或者直接從http://ziparchive.googlecode.com/files/ZipArchive.zip 下載

把minizip文件夾和ZipArchive.h以及ZipArchive.mm文件添加到你的工程中

因為ZipArchive不支持ARC,所以如果你的工程開啟了ARC,那么就需要對ZipArchive設置一下。在ZipArchive.mm編譯選項中,增加-fno-objc-arc即可。

最后,需要為工程鏈接libz動態鏈接庫

至此,ZipArchive已經集成到你的工程中了,編譯工程,應該可以編譯成功。可能會有一些警告,這無關緊要,不影響編譯。但是作為一個態度嚴謹的程序員,我強烈建議你看一下這些警告是怎么出現的,解決它們。請記住:在你的工程中,警告應該和錯誤一樣被嚴肅處理!

下載和解壓縮文件

接 下來就向大家展示在你的工程中如何從網上下載zip文件,解壓縮,並讀取zip壓縮包中的文件內容。處於演示考慮,主要的目的是向大家演示 ZipArchive接口的使用方法,所以代碼的錯誤處理和條件檢查並沒有做過多的考量,在實際的工程中,還是需要大家自己做更為嚴格的條件檢查和錯誤處 理工作

示例工程的運行效果如下圖:

工 程中只是在ViewController中增加了一個UIImageView和一個UILabel。我們將從網絡上下載zip文件,zip文件中包含一張 圖片和一個文本文件。下載解壓后,圖像會被渲染到UIImageView中,而文本會作為UILabel的內容展示。示例代碼在文章末尾。希望讀者朋友們 自行下載,編譯,查看效果

好,接下來講一講具體的實現:

1.引入ZipArchive的頭文件

  1. #import "ZipArchive.h"
復制代碼

2.下載zip文件

  1.     dispatch_queue_t queue = dispatch_get_global_queue(
  2.                                                        DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  3.     dispatch_async(queue, ^{
  4.         NSURL *url = [NSURL URLWithString:@"http://www.icodeblog.com/wp-content/uploads/2012/08/zipfile.zip"];
  5.         NSError *error = nil;
  6.         NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
  7.         if(!error)
  8.             NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  9.             NSString *path = [paths objectAtIndex:0];
  10.             NSString *zipPath = [path stringByAppendingPathComponent:@"zipfile.zip"];
  11.             [data writeToFile:zipPath options:0 error:&error];
  12.             if(!error)
  13.                 // TODO: Unzip
  14.                 NSLog(@"Error saving file %@",error);
  15.             NSLog(@"Error downloading zip file: %@", error);
復制代碼

上面這段代碼的主要作用就是從iCodeBlog上下載一個zip文件,並寫入到應用的緩存目錄中

現在zip文件已經下載下來了,接下來就是要解壓縮,並將解壓縮出來的文件利用起來

3. 解壓縮已下載的zip文件

在第二步中,我們已經把zip文件下載到/Library/Caches/zipfile.zip,現在來解壓縮

把上面代碼中的//TODO: Unzip用下面的代碼替換掉

  1. ZipArchive *za = [[ZipArchive alloc] init];
  2. if ([za UnzipOpenFile: zipPath]) {      
  3.     BOOL ret = [za UnzipFileTo: path overWrite: YES];
  4.     if (NO == ret){} [za UnzipCloseFile];
  5.     NSString *imageFilePath = [path stringByAppendingPathComponent:@"photo.png"];
  6.     NSString *textFilePath = [path stringByAppendingPathComponent:@"text.txt"];
  7.     NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath options:0 error:nil];
  8.     UIImage *img = [UIImage imageWithData:imageData];
  9.     NSString *textString = [NSString stringWithContentsOfFile:textFilePath
  10.         encoding:NSASCIIStringEncoding error:nil];
  11.     dispatch_async(dispatch_get_main_queue(), ^{
  12.         self.imageView.image = img;
  13.         self.label.text = textString;
復制代碼

對上面的代碼做一個簡單的解釋:

1. 在內存中解壓縮文件

2. 將解壓縮的內容寫到緩存目錄中

3. 使用解壓縮后的文件

4. 更新UI

非常簡單吧!

壓縮文件

接下來看一下怎么進行文件壓縮。在上面的步驟中,我們已經把一個zip文件解壓縮到緩存目錄中。現在我們再把解壓縮出來的文件重新壓縮為一個zip文件,並把這個zip文件寫入到Documents目錄里去(OMG,這兩個文件太慘了,被反復蹂躪)

在示例工程代碼中,我已經增加了一個按鈕,並和一個IBAction相關聯,按鈕的處理函數名為zipFilesBUttonPressed:,具體代碼如下:

  1. - (IBAction)zipFilesButtonPressed:(id)sender
  2.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  3.     NSString *docspath = [paths objectAtIndex:0];
  4.     paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  5.     NSString *cachePath = [paths objectAtIndex:0];
  6.     NSString *zipFile = [docspath stringByAppendingPathComponent:@"newzipfile.zip"];      
  7.     ZipArchive *za = [[ZipArchive alloc] init];
  8.     [za CreateZipFile2:zipFile];
  9.     NSString *imagePath = [cachePath stringByAppendingPathComponent:@"photo.png"];
  10.     NSString *textPath = [cachePath stringByAppendingPathComponent:@"text.txt"];
  11.     [za addFileToZip:imagePath newname:@"NewPhotoName.png"];
  12.     [za addFileToZip:textPath newname:@"NewTextName.txt"];
  13.     BOOL success = [za CloseZipFile2];   
  14.     NSLog(@"Zipped file with result %d",success);
復制代碼

簡單解釋一下上面代碼的意思:

1. 獲取Documents目錄,新的zip文件要寫入到這個目錄里。

2. 獲取Caches目錄,要進行壓縮的文件在這個目錄里。

3. 獲取zip文件的全路徑名。

4. 創建一個ZipArchive實例,並創建一個內存中的zip文件。需要注意的是,只有當你調用了CloseZipFile2方法之后,zip文件才會從內存中寫入到磁盤中去

5. 獲取要被壓縮的文件的全路徑

6. 把要壓縮的文件加入到zip對象中去,加入的文件數量沒有限制,也可以加入文件夾到zip對象中去。

7. 把zip從內存中寫入到磁盤中去。

當點擊按鈕之后,在應用的Documents文件夾下應該有一個叫newzipfile.zip的文件。解壓這個文件,就能解壓出那兩個被反復蹂躪的文件來

結論

現在你知道如何使用ZipArchive來壓縮和解壓縮文件了。享受ZipArchive的便利吧。示例工程已經很好的展示了這些基本用法,大家可以好好研究下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM