2012-07-19 72 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