【问题标题】:C# WPF Detecting Extract Completion with DotNetZip?C# WPF 使用 DotNetZip 检测提取完成?
【发布时间】:2011-08-07 02:51:24
【问题描述】:

我一直在尝试使用 Ionic.Zip (DotNetZip) 通过程序提取下载的 zip 文件。但是当我试图检测提取过程何时完成时,我被卡住了。该库包含一个 ExtractProgress 事件,因此我尝试通过进度条检测它,但它会根据每个条目作为单个条目而不是整个 zip 来更新进度条。因此,一旦第一个文件条目被解压缩,它就会认为它“已完成”。有谁知道使用 DotNetZip 检测提取整个 zip 完成的方法吗?

【问题讨论】:

  • 你应该展示一些你所做的代码

标签: c# wpf extraction dotnetzip


【解决方案1】:

通过快速浏览DotNetZip Codeplex 上的示例,您可以一次打开一个项目的拉链。要向用户报告进度,请像这样使用BackgroundWorker

public void ExtractFile(string zipToUnpack, string unpackDirectory)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.WorkerReportsProgress = true;
    worker.ProgressChanged += (o, e) => { Console.WriteLine("Percent completed:" + e.ProgressPercentage); };
    worker.DoWork += (o, e) =>
    {
        using (ZipFile zip = ZipFile.Read(zipToUnpack))
        {  
            int step = (zip.Count / 100.0);
            int percentComplete = 0;
            foreach (ZipEntry file in zip)
            {
                file.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
                percentComplete += step;
                worker.ReportProgress(percentComplete);
            }
        }
    };

    worker.RunWorkerAsync();
}

另外,刚刚看了Codeplex上的源代码,它是一个相当完整的产品,所以应该有很多方法可以实现你想要的;我给的只是其中之一。

HTH,

【讨论】:

  • @Cheeso:我刚刚修复了示例中的编译错误:worker.ProgressChanged += (o, e) { Console 应该是 worker.ProgressChanged += (o, e) => { Console
【解决方案2】:

如果你有这样的代码:

using (var zip = ZipFile.Read("whatever.zip"))
{
    zip.ExtractProgress += MyExtractProgress;
    numEntries = zip.Entries.Count;
    foreach (var e in zip) 
    {
        e.Extract();
    }
}

...您将获得提取进度事件。 ExtractProgressEventArgs 类记录在here。 在事件 args 类中,有一个 EventType 字段,用于描述您收到的事件。这些类型被描述为here

提取开始前条目有事件类型,提取完成后(条目)。如果您想跟踪到该级别,还有一个事件类型会为每个解压缩的数据块触发。因此,您可以获得数千个特定提取的事件。如果您跟踪条目的数量,那么您就知道预期有多少“之后”事件,并且您可以在收到适当数量的 after 事件时声明提取完成。

如上所示,如果您在循环中提取每个条目,则库无法发出“提取完成”事件。这是因为它不知道您是否将循环继续到最后,或者可能在中间停止。它无法知道。

如果你调用 zip.ExtractAll(),像这样:

using (var zip = ZipFile.Read("whatever.zip"))
{
    zip.ExtractProgress += MyExtractProgress;
    zip.ExtractAll(extractDirectory);
}

...然后 DotNetZip 将发出“所有条目已被提取”事件类型。这也在我上面提供的文档链接中进行了描述。

所以你有一些选择。

【讨论】:

  • MyExtractProgress 到底是什么,顺便说一句,它给了我错误:Zipfile 不包含“读取”的定义
【解决方案3】:

有一个名为 Extracting_AfterExtractAll 的 EventType,您可以使用它来检查 ExtractAll 操作是否已完成:

http://www.nudoq.org/#!/Packages/DotNetZip/Ionic.Zip/ZipProgressEventType/F/Extracting_AfterExtractAll

    private void UnZipFile(zipFilePath)
    {
        using (ZipFile zip = new ZipFile(zipFilePath))
        {
            zip.ExtractProgress += zip_ExtractProgress;
            zip.ExtractAll(Path.GetDirectoryName(zipFilePath));
        }
    }

    static void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
    {
        if (e.EventType == ZipProgressEventType.Extracting_AfterExtractAll)
            zipExtractFinished = true;
    }

【讨论】:

    【解决方案4】:

    而不是使用您自己的工作人员。还有提交者提到的 ExtractProgress 事件,此外还可以查询 zip 中的项目数。将这两者结合起来,您就获得了进度事件,并能够根据项目总数跟踪进度。 AFAIK 没有表明提取结束的事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 2011-08-03
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多