2012-07-19 35 views
14

Tôi đang xây dựng một ứng dụng kiểu metro cho windows 8 và tôi có tệp zip mà tôi đang tải xuống từ dịch vụ web và tôi muốn giải nén nó.giải nén tệp ZIP trên windows 8 C#

Tôi đã xem mẫu để nén và giải nén, nhưng phải mất một tệp duy nhất để nén/giải nén nó. Tôi có toàn bộ cấu trúc thư mục mà tôi cần trích xuất.

Dưới đây là những gì tôi có cho đến nay:

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); 
} 

Nhưng điều này là không tốt, biến bytesDecompressed luôn kích cỡ bằng không, nhưng File zip là 1,2MB

Bất kỳ trợ giúp ở đây sẽ rất đánh giá cao.

EDIT: trả lời, nhờ Mahantesh

Đây là mã cho giải nén một tập tin:

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

tôi đã triển khai mã này để giải nén tệp zip có trong thư mục ApplicationData.Current.LocalFolder của tôi. Nhưng zip chứa thư mục và thư mục con. Vì vậy, mã, khi chạy, cung cấp cho "Truy cập bị từ chối lỗi" trong khi thực hiện chờ đợi outputFile.OpenStreamForWriteAsync() hoạt động trong các thư mục con. Tuy nhiên, lỗi được nhìn thấy ở bất kỳ thư mục con ngẫu nhiên nào khi mã được chạy nhiều lần. Bất kỳ ý tưởng về điều này? –

+0

Ok .. lỗi là tôi đã thực hiện phương pháp UnZipFile là phương pháp tĩnh mà tôi không nên làm ... –

Trả lời

13

Trong các ứng dụng phong cách Metro, bạn làm việc với các tập tin nén bằng cách sử dụng các phương pháp trong ZipArchive, ZipArchiveEntry , DeflateStream và GZipStream lớp học.

Tham khảo: UnZip File in Metro

Tham khảo: Folder zip/unzip in metro c#

+0

cảm ơn, đã cập nhật câu hỏi của tôi để hiển thị câu trả lời – Mark

4

Dựa trên mã và đề xuất của bạn, tôi đã đưa ra một trong đó hỗ trợ khai thác các thư mục, mà là một trong những nhu cầu của tôi:

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

thì tốt, nhưng cách bạn nhận được thông báo khi toàn bộ quá trình hoàn thành? – balint

+1

Nhận ra rằng tôi đang sử dụng ** đang chờ ** cho phương thức 'CreateRecursiveFolder' và' ExtractFile', vì vậy nó sẽ không thực sự không đồng bộ, và phương thức 'UnZipFile' sẽ chỉ trả lại khi mọi thứ đã sẵn sàng. Bạn phải sử dụng mệnh đề 'await' khi gọi' UnZipFile'. – Tuco

+0

@Tuco Tôi đã triển khai mã này để giải nén tệp zip có trong thư mục ApplicationData.Current.LocalFolder của tôi. Nhưng zip chứa thư mục và thư mục con. Vì vậy, mã cho "Truy cập bị từ chối lỗi" trong khi giải nén dữ liệu trong các thư mục con này. Tuy nhiên, lỗi được nhìn thấy ở bất kỳ thư mục con ngẫu nhiên nào khi mã được chạy nhiều lần. Bất kỳ ý tưởng về điều này? –

Các vấn đề liên quan