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

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

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

爲何我須要解壓縮文件緩存

有許多緣由能解釋爲何我要在工程中使用壓縮和解壓縮功能,下面是幾個常見的緣由:服務器

蘋果App Store的50M下載限制網絡

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

動態更新內容ide

這 一點在上面已經提過了。若是應用所須要的資源須要動態更新,一種常見的作法是更新資源,從新打包,從新提交到App store,這樣作你須要等待漫長的審覈、上架時間。通常狀況下是一週左右的時間。更好的方法是將這些資源打包放置在服務器上,App從服務器(或者雲存 儲)上下載,而後解壓。這樣作的好處顯而易見,那就是能夠快速更新,動態更新,不須要從新打包、上傳、審覈,省時省力。svn

從Web上下載zip文件函數

Safari和郵件程序都不支持zip的查看,經過ZipArchive你就能夠爲你的設備增長查看zip文件的能力了,儘管App Store裏已經有一些App支持這些功能了google

工程設置

首先從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的便利吧。示例工程已經很好的展現了這些基本用法,你們能夠好好研究下。

相關文章
相關標籤/搜索