1

为了用要提取的文件数更新进度条。我的程序正在检查一个 Zip 文件列表并收集其中的文件数量。合并后的文件数约为 22000 个。

我正在使用的代码:

    foreach (string filepath in zipFiles)
    {
        ZipArchive zip = ZipFile.OpenRead(filepath);
        archives.Add(zip);
        filesCounter += zip.Entries.Count;
    }

但是,它看起来像是zip.Entries.Count在进行某种遍历,并且这个计数需要很长时间才能完成(如果互联网连接不好,则需要几分钟甚至更多)。

为了了解这可以改善多少,我将上面的内容与 7-Zip 的性能进行了比较。我拿了一个包含约 11000 个文件和文件夹的 zip 文件:

  1. 2 秒打开 7-Zip 存档。
  2. 1秒获取文件属性
  3. 在属性中,我可以看到 10016 个文件 + 882 个文件夹 - 这意味着需要 7-Zip ~3 秒才能知道 Zip 文件中有 10898 个条目。

7-Zip 属性

任何快速计算文件数量的想法、建议或任何替代方法将不胜感激。

  • 使用DotNetZip 计数实际上要快得多,但由于一些内部官僚问题,我无法使用它。我需要一个不涉及第三方库的解决方案,我仍然可以使用 Microsoft 标准库。
4

1 回答 1

0

我的进度条问题通过采用新方法解决了。

我只是累积所有 ZIP 文件的大小,作为最大大小。现在,对于提取的每个单独文件,我将其压缩大小添加到进度中。这样,进度条不会显示文件的数量,而是显示未压缩的进度(例如,如果我总共有 4GB 要提取,当进度条为 1/4 绿色时,我知道我提取了 1GB)。看起来更好地代表了现实。

foreach (string filepath in zipFiles)
{
    ZipArchive zip = ZipFile.OpenRead(filepath);
    archives.Add(zip);

    // Accumulating the Zip files sizes.
    filesCounter += new FileInfo(filepath).Length; 
}

// To utilize multiple processors it is possible to activate this loop
// in a thread for each ZipArchive -> currentZip!
// :
// :

foreach (ZipArchiveEntry entry in currentZip.Entries) {
    // Doing my extract code here.
    // :
    // :

    // Accumulate the compressed size of each file.
    compressedFileSize += entry.CompressedLength

    // Doing other stuff
    // :
    // :
}

所以提高性能的问题zip.Entries.Count仍然存在,我仍然有兴趣知道如何解决这个特定问题(7Zip 做了什么这么快 - 可能是他们使用 DotNetZip 或其他 C++ 库)

于 2020-05-19T22:00:00.453 回答