我一直在尝试使用 Ionic.Zip (DotNetZip) 通过程序提取下载的 zip 文件。但是当我试图检测提取过程何时完成时,我被卡住了。该库包含一个 ExtractProgress 事件,因此我尝试通过进度条检测它,但它会根据每个条目作为单个条目而不是整个 zip 来更新进度条。因此,一旦第一个文件条目被解压缩,它就会认为它“已完成”。有谁知道使用 DotNetZip 检测提取整个 zip 完成的方法?
4 回答
通过快速浏览DotNetZip Codeplex上的示例,您可以一次打开一个项目的压缩包。要向用户报告进度,请使用BackgroundWorker
like so。
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 上的源代码,它是一个相当完整的产品,所以应该有很多方法可以实现你想要的;我给的只是其中之一。
高温下,
如果你有这样的代码:
using (var zip = ZipFile.Read("whatever.zip"))
{
zip.ExtractProgress += MyExtractProgress;
numEntries = zip.Entries.Count;
foreach (var e in zip)
{
e.Extract();
}
}
...您将获得提取进度事件。此处记录了 ExtractProgressEventArgs 类。在事件 args 类中,有一个 EventType 字段,用于描述您收到的事件。这些类型在此处进行了描述。
在提取开始之前为条目提供事件类型,在提取完成之后(对于条目)。如果您想跟踪到该级别,还有一个事件类型会为每个解压缩的数据块触发。因此,您可以获得数千个特定提取的事件。如果您跟踪条目的数量,那么您就知道预期有多少“后续”事件,并且您可以在收到适当数量的后续事件时声明提取已完成。
如果您在循环中提取每个条目,则库无法发出“提取完成”事件,如上所示。这是因为它不知道您是否将循环继续到最后,或者可能在中间停止。它无法知道。
如果你调用 zip.ExtractAll(),像这样:
using (var zip = ZipFile.Read("whatever.zip"))
{
zip.ExtractProgress += MyExtractProgress;
zip.ExtractAll(extractDirectory);
}
...然后 DotNetZip 将发出“所有条目已被提取”事件类型。这也在我上面提供的文档链接中进行了描述。
所以你有一些选择。
有一个名为Extracting_AfterExtractAll的 EventType ,您可以使用它来检查 ExtractAll 操作是否已完成:
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;
}
而不是为此使用您自己的工作人员.. 还有提交者提到的 ExtractProgress 事件,此外还可以查询 zip 中的项目数。将这两者结合起来,您就获得了进度事件,并能够根据项目总数跟踪进度。AFAIK 没有表明提取结束的事件。