我一直在尝试使用Ionic.Zip(DotNetZip)通过程序提取下载的zip文件。但是当我试图检测提取过程何时完成时,我被困住了。该库包含一个ExtractProgress事件,因此我尝试通过进度条检测它,但它会根据每个条目将进度条更新为单个条目而不是整个zip。因此,只要解压缩第一个文件条目,就会认为它已“完成”。有没有人知道用DotNetZip检测整个拉链完成的提取方法?
答案 0 :(得分:3)
通过快速浏览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,
答案 1 :(得分: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。
在提取开始之前的事件类型用于条目,在提取完成之后(用于条目)。如果您想跟踪到该级别,还会为每个解压缩的数据块触发一个事件类型。因此,您可以为特定提取获取数千个事件。如果您跟踪条目数,那么您就知道预期会有多少“之后”事件,并且当您在事件之后收到适当数量的时,可以声明提取已完成。
如上所示,如果要提取循环中的每个条目,则库不能发出“提取已完成”事件。这是因为它不知道你是否会继续你的循环到最后,或者可能在中间停止。它无法知道。
如果您调用zip.ExtractAll(),请执行以下操作:
using (var zip = ZipFile.Read("whatever.zip"))
{
zip.ExtractProgress += MyExtractProgress;
zip.ExtractAll(extractDirectory);
}
...然后DotNetZip将发出“所有条目已被提取”的事件类型。我在上面提供的文档链接中也对此进行了描述。
所以你有一些选择。
答案 2 :(得分:1)
有一个名为 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;
}
答案 3 :(得分:0)
而不是使用你自己的工作人员..还有提交者提到的ExtractProgress事件,而且可以查询zip中的项目数。将这两者结合起来,您就可以获得进度事件,并能够根据项目总数跟踪进度。 AFAIK没有表明提取结束的事件。