2015-05-14 17 views
16

我嘗試解壓僅包含一個項目(超過100MB)的大zip文件,並希望在解壓縮過程中顯示進度。如何解壓縮包含一個文件的大型壓縮文件並用swift獲取以字節爲單位的進度?

我發現解決方案的進度可以根據解壓縮文件的數量來確定,但在我的情況下,我只有一個大文件。所以我想這一定是由解壓縮的字節數決定的?

其實我使用SSZipArchive用下面的代碼工作正常:

var myZipFile:NSString="/Users/user/Library/Developer/CoreSimulator/Devices/mydevice/ziptest/testzip.zip"; 
    var DestPath:NSString="/Users/user/Library/Developer/CoreSimulator/Devices/mydevice/ziptest/"; 


    let unZipped = SSZipArchive.unzipFileAtPath(myZipFile as! String, toDestination: DestPath as! String); 

我發現這個無解。

有沒有人有提示,樣本或鏈接到樣本?

UPDATE: 下面的代碼看起來如預期它會工作,但處理程序將只調用一次(在解壓結束)時,只有一個文件解壓縮:

func unzipFile(sZipFile: String, toDest: String){ 

     SSZipArchive.unzipFileAtPath(sZipFile, toDestination: toDest, progressHandler: { 
      (entry, zipInfo, readByte, totalByte) -> Void in 


      println("readByte : \(readByte)") // <- This will be only called once, at the end of unzipping. My 500MB Zipfile holds only one file. 
      println("totalByte : \(totalByte)") 


      //Asynchrone task 
      dispatch_async(dispatch_get_main_queue()) { 
       println("readByte : \(readByte)") 
       println("totalByte : \(totalByte)") 

       //Change progress value 

      } 
      }, completionHandler: { (path, success, error) -> Void in 
       if success { 
        //SUCCESSFUL!! 
       } else { 
        println(error) 
       } 
     }) 

    } 

更新2:

作爲「馬丁R」在SSArchive分析,它不可能。 是否有任何其他方式來解壓文件並顯示基於千字節的進度?

UPDATE 3:

我改變了SSZipArchive.m溶液用 「魯普」 解釋如下之後。也許別人可以用這個太:

FILE *fp = fopen((const char*)[fullPath UTF8String], "wb"); 
       while (fp) { 
        int readBytes = unzReadCurrentFile(zip, buffer, 4096); 

        if (readBytes > 0) { 
         fwrite(buffer, readBytes, 1, fp); 
         totalbytesread=totalbytesread+4096; 
         // Added by me 
         if (progressHandler) 
         { 
          progressHandler(strPath, fileInfo, currentFileNumber, totalbytesread); 
         } 
         // End added by me 

        } else { 
         break; 
        } 
       } 
+0

你正在使用什麼解壓縮庫? – chedabob

+0

我與其他人一起使用SSZipArchive –

+0

如果我正確理解了SSZipArchive的源代碼,則會爲每個文件調用一次進度處理程序,並且在解壓縮單個文件時不提供任何選項以獲取進度。 –

回答

1

達到你想要什麼,你將不得不修改SSZipArchive的內部代號。

SSZipArchive使用minizip提供壓縮功能。你可以在這裏看到minizip unzipping API:unzip.h

在SSZipArchive.m中,您可以從fileInfo variable獲得解壓縮文件的解壓縮大小。

你可以看到解壓縮後的內容被讀取here

FILE *fp = fopen((const char*)[fullPath UTF8String], "wb"); 
while (fp) { 
    int readBytes = unzReadCurrentFile(zip, buffer, 4096); 
    if (readBytes > 0) { 
     fwrite(buffer, readBytes, 1, fp); 
    } else { 
     break; 
    } 
} 

您將需要readBytes和未壓縮的文件大小來計算單個文件的進度。您可以添加一個新的委託給SSZipArchive將這些數據發送回調用代碼。

+0

非常感謝您的幫助。我想這是正確的答案,這就是爲什麼我接受它。我沒有嘗試,但我看到了解決方案。當然,如果有人可以將代碼粘貼到SSZipArchive.m中,那麼我不會感到不快,因爲我對swift更熟悉:-) –

+0

另一種建議:如果您對Obj-C不滿意,可以直接使用minizip(而不是使用SSZipArchive) - Swift可以直接鏈接到C代碼。 – roop

+0

非常感謝您的建議。我會嘗試... –

2

你可以試試這個代碼:

SSZipArchive.unzipFileAtPath(filePath, toDestination: self.destinationPath, progressHandler: { 
(entry, zipInfo, readByte, totalByte) -> Void in 
     //Create UIProgressView 
     //Its an exemple, you can create it with the storyboard... 
     var progressBar : UIProgressView? 
     progressBar = UIProgressView(progressViewStyle: .Bar) 
     progressBar?.center = view.center 
     progressBar?.frame = self.view.center 
     progressBar?.progress = 0.0 
     progressBar?.trackTintColor = UIColor.lightGrayColor(); 
     progressBar?.tintColor = UIColor.redColor(); 
     self.view.addSubview(progressBar) 

     //Asynchrone task     
     dispatch_async(dispatch_get_main_queue()) { 
      println("readByte : \(readByte)") 
      println("totalByte : \(totalByte)")        

      //Change progress value 
      progressBar?.setProgress(Float(readByte/totalByte), animated: true) 
      //If progressView == 100% then hide it 
      if readByte == totalByte { 
       progressBar?.hidden = true 
      } 
     } 
}, completionHandler: { (path, success, error) -> Void in 
    if success { 
     //SUCCESSFUL!! 
    } else { 
     println(error) 
    } 
}) 

我希望我已經幫你!

Ysee

+0

非常感謝您的幫助。我會盡快檢查。聽起來很有希望。 –

+0

感謝您的幫助,但它無法正常工作。當我調試你的代碼時,它只會調用progressHandler。這是當Zipfile被解壓縮時。在我的情況下,我只在zip中有一個文件,所以我想它只會調用每個解壓縮文件的處理程序。在我的情況下,這意味着它將在解壓縮結束時被調用,並且在解壓縮過程中不會顯示任何進度。有什麼建議麼 ? –

+0

你可以發佈你的代碼嗎? – Maybe1