2012-07-19 80 views
14

我正在爲Windows 8構建一個metro風格的應用程序,並且我有一個zip文件,我從Web服務下載並且我想提取它。在Windows 8上解壓ZIP文件C#

我已經看到了壓縮和解壓縮的示例,但是需要一個文件來壓縮/解壓縮它。我有一個完整的目錄結構,我需要提取。

這是我到目前爲止有:

var appData = ApplicationData.Current; 
var file = await appData.LocalFolder.GetItemAsync("thezip.zip") as StorageFile; 
var decompressedFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("tempFileName", CreationCollisionOption.GenerateUniqueName); 
using (var decompressor = new Decompressor(await file.OpenSequentialReadAsync())) 
using (var decompressedOutput = await decompressedFile.OpenAsync(FileAccessMode.ReadWrite)) 
{ 
    var bytesDecompressed = await RandomAccessStream.CopyAsync(decompressor, decompressedOutput); 
} 

但是,這不是好,bytesDecompressed變量始終是零大小,但壓縮文件1.2MB

任何幫助這裏將不勝讚賞。

編輯:回答,感謝Mahantesh

這裏是解壓文件的代碼:通過使用ZipArchive,ZipArchiveEntry方法

private async void UnZipFile() 
{ 
    var folder = ApplicationData.Current.LocalFolder; 

    using (var zipStream = await folder.OpenStreamForReadAsync("thezip.zip")) 
    { 
     using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length)) 
     { 
      await zipStream.CopyToAsync(zipMemoryStream); 

      using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read)) 
      { 
       foreach (ZipArchiveEntry entry in archive.Entries) 
       { 
        if (entry.Name != "") 
        { 
         using (Stream fileData = entry.Open()) 
         { 
          StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting); 
          using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync()) 
          { 
           await fileData.CopyToAsync(outputFileStream); 
           await outputFileStream.FlushAsync(); 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

我已經實現了這個代碼來解壓縮在我的ApplicationData.Current.LocalFolder文件夾中存在的zip文件。但該zip包含文件夾和子文件夾。因此,代碼在運行時會在這些子文件夾中執行await outputFile.OpenStreamForWriteAsync()操作時給出「訪問被拒絕錯誤」。但是,錯誤發生在代碼運行多次的任何隨機子文件夾中。對此有任何想法? – 2014-11-26 05:35:50

+0

好吧..錯誤是我已經使UnZipFile方法作爲靜態方法,我不應該這樣做... – 2014-12-22 06:06:21

回答

4

基於您的代碼和建議,我想出了一個支持文件夾中提取,這是我需要一個:

private async void UnZipFile(string file) 
{ 
    var folder = ApplicationData.Current.LocalFolder; 

    using (var zipStream = await folder.OpenStreamForReadAsync(file)) 
    { 
     using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length)) 
     { 
      await zipStream.CopyToAsync(zipMemoryStream); 

      using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read)) 
      { 
       foreach (ZipArchiveEntry entry in archive.Entries) 
       { 

        if (entry.Name == "") 
        { 
         // Folder 
         await CreateRecursiveFolder(folder, entry); 
        } 
        else 
        { 
         // File 
         await ExtractFile(folder, entry); 
        } 
       } 
      } 
     } 
    } 
} 

private async Task CreateRecursiveFolder(StorageFolder folder, ZipArchiveEntry entry) 
{ 
    var steps = entry.FullName.Split('/').ToList(); 

    steps.RemoveAt(steps.Count() - 1); 

    foreach (var i in steps) 
    { 
     await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists); 

     folder = await folder.GetFolderAsync(i); 
    } 
} 

private async Task ExtractFile(StorageFolder folder, ZipArchiveEntry entry) 
{ 
    var steps = entry.FullName.Split('/').ToList(); 

    steps.RemoveAt(steps.Count() - 1); 

    foreach (var i in steps) 
    { 
     folder = await folder.GetFolderAsync(i); 
    } 

    using (Stream fileData = entry.Open()) 
    { 
     StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting); 

     using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync()) 
     { 
      await fileData.CopyToAsync(outputFileStream); 
      await outputFileStream.FlushAsync(); 
     } 
    } 
} 
+0

這很好,但是如何在整體時得到通知過程完成? – balint 2012-09-26 18:43:28

+1

意識到我正在使用** await **來創建'CreateRecursiveFolder'和'ExtractFile'方法,所以它不會是真正的異步方式,並且'UnZipFile'方法只會在所有東西都準備好時返回。您必須使用調用'UnZipFile'時調用'await'子句。 – Tuco 2012-09-27 00:12:23

+0

@Tuco我已經實現了這段代碼來解壓縮出現在我的ApplicationData.Current.LocalFolder文件夾中的zip文件。但該zip包含文件夾和子文件夾。因此,在解壓縮這些子文件夾中的數據時,代碼會給出「拒絕訪問錯誤」。但是,錯誤發生在代碼運行多次的任何隨機子文件夾中。對此有任何想法? – 2014-11-26 05:25:54