SharpCompress&LZMA2 7z存档-提取特定文件的速度非常慢。为什么?备择方案?

Bog*_*gey 3 c# compression performance lzma sharpcompress

我有一个使用LZMA2压缩(压缩级别:超)的7zip存档。该档案文件包含1,749个文件,最初的总大小为661mb。压缩文件的大小为39mb。

现在,我正在尝试使用C#从此存档中提取一个很小的文件(大约200kb)。

我从IArchive(工作速度相对较快)中获取了相应的IArchiveEntry,但是随后调用IArchiveEntry.WriteToFile(targetPath)大约需要33秒!同样,如果我改为写入内存流,时间也很长。(编辑:当我在压缩级别=正常的7z LZMA2存档上运行此文件时,它仍需要9秒钟)

当我在实际的7zip应用程序中打开相同的存档并从那里提取相同的文件时,它只需要2-3秒。我怀疑这是多核(7zip)与单核(可能是ShapCompress吗?),但是我没有注意到7zip解压缩期间的CPU使用率激增。.也许它太快了,以至于无法注意到。

有人知道SharpCompress这么慢的速度可能是什么问题吗?我可能会缺少某些设置或使用了错误的工厂(ArchiveFactory)吗?

如果不是-是否有任何C#库在解压缩该库时可能会更快?

作为参考,这是我如何使用SharpCompress提取的草图:

private void Extract()
    {
        using(var archive = GetArchive())
        {
          var entryPath = /* ... path to entry .. */
          var entry = TryGetEntry(archive, entryPath);
          entry.WriteToFile(some_target_path);
        }
    }


    private IArchive GetArchive()
    {
        string path = /* .. path to my .7z file */;
        return ArchiveFactory.Open(path);
    }

    private IArchiveEntry TryGetEntry(IArchive archive, string path)
    {
        path = path.Replace("\\", "/");

        foreach (var entry in archive.Entries)
        {
            if (!entry.IsDirectory)
            {
                if (entry.Key == path)
                    return entry;
            }
        }

        return null;
    }
Run Code Online (Sandbox Code Playgroud)

更新:作为一个临时解决方案,我现在将7zip SDK中的7zr.exe包含在我的应用程序中,并在新流程中运行该流程以提取单个文件,并将流程的输出读取为二进制流。与SharpCompress的〜33秒相比,此方法的工作时间约为3秒。现在可以工作,但是有点难看..仍然很好奇为什么SharpCompress在那里这么慢

Axi*_*ili 5

这条线是问题

foreach (var entry in archive.Entries)
Run Code Online (Sandbox Code Playgroud)

这里描述问题(即,如果有100个文件,则将第一个文件解压缩100次,将第二个文件解压缩99次,依此类推)

您需要使用阅读器(仅转发)。请参阅API
但是那里的示例代码不支持7z。

对于7z,您可以使用archive.ExtractAllEntries(),例如。

var reader = archive.ExtractAllEntries();
while (reader.MoveToNextEntry())
{
    if (!reader.Entry.IsDirectory)
        reader.WriteEntryToDirectory(extractDir, new ExtractionOptions() { ExtractFullPath = false, Overwrite = true });
}
Run Code Online (Sandbox Code Playgroud)

它将更快。