1

我正在开发一个 Windows 应用商店应用程序概念证明,它将打开一个 .zip 文件并将内容提取到特定于应用程序的漫游文件夹。我查看了几个流行的库以提取内容,结果发现这些库不支持 Windows 应用商店应用程序(至少目前还不支持)。所以,我决定使用ZipArchive。我在按钮单击处理程序中有以下代码:

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    var fileOpenPicker = new FileOpenPicker();
    fileOpenPicker.FileTypeFilter.Add(".zip");
    var openedFile = await fileOpenPicker.PickSingleFileAsync();

    var booksFolder = await Windows.Storage.ApplicationData.Current.RoamingFolder.CreateFolderAsync("Stuff", CreationCollisionOption.OpenIfExists);
    var folder = await booksFolder.CreateFolderAsync(openedFile.Name.Replace(".zip", string.Empty), CreationCollisionOption.ReplaceExisting);

    using (var stream = await openedFile.OpenStreamForReadAsync())
    {
        using (var zip = new ZipArchive(stream, ZipArchiveMode.Read))
        {
            foreach (var entry in zip.Entries)
            {
                using (var entryStream = entry.Open())
                {
                    var file = await folder.CreateFileAsync(entry.Name);
                    using (var decompressedStream = await file.OpenStreamForWriteAsync())
                    {
                        using (var deflateStream = new DeflateStream(entryStream, CompressionMode.Decompress))
                        {
                            await deflateStream.CopyToAsync(decompressedStream, (int)entry.Length);
                        }
                    }
                }
            }
        }
    }
}

但是,我InvalidDataException上线了

await deflateStream.CopyToAsync(decompressedStream, (int)entry.Length);

以下是异常的详细信息:

System.IO.InvalidDataException was unhandled by user code
  HResult=-2146233087
  Message=Unknown block type. Stream might be corrupted.
  Source=System
  StackTrace:
       at System.IO.Compression.DeflateStream.EndRead(IAsyncResult asyncResult)
       at System.IO.Stream.<BeginEndReadAsync>b__e(Stream stream, IAsyncResult asyncResult)
       at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.IO.Stream.<CopyToAsyncInternal>d__2.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
       at POC.MoviePlayer.GroupedItemsPage.<Button_Click_1>d__4.MoveNext() in c:\Users\Brent\Documents\Visual Studio 2012\Projects\POC.MoviePlayer\POC.MoviePlayer\GroupedItemsPage.xaml.cs:line 108
  InnerException: 

我尝试导入的 .zip 文件是使用 Windows 资源管理器的发送到压缩(压缩)文件夹选项创建的。我还尝试使用 ZipArchive 在代码中创建一个 .zip 文件,但我也遇到了更多关于该代码的异常。因为无论如何这都不是我理想的用例,所以我不会包含我的代码来创建 .zip,除非它对某人有用。

我希望有人可以在上面的代码中看到我的方式的错误,或者提供一个链接到一个可靠的库来处理最好是开源的 zip 文件。这位沮丧的开发人员将非常感谢您的帮助。

4

1 回答 1

0

您不必解压缩entry.Open(). 它已经解压了。

您还可以使用ZipFileExtensions.ExtractToDirectory(http://msdn.microsoft.com/en-us/library/system.io.compression.zipfileextensions.extracttodirectory.aspx) 来简化您的代码。

于 2012-12-26T19:22:38.450 回答