2017-04-25 66 views
0

我有一個用LZMA2壓縮(壓縮級別:ultra)製作的7zip壓縮文件。 該檔案包含1,749個文件,總共原始大小爲661mb。 壓縮文件大小爲39mb。SharpCompress&LZMA2 7z存檔 - 非常緩慢地提取特定文件。爲什麼?備擇方案?

現在我試圖用C#從這個壓縮文件中提取一個很小的(〜200kb'ish)單個文件。

我從IArchive獲得相應的IArchiveEntry(工作相對較快), ,但隨後調用IArchiveEntry.WriteToFile(targetPath)需要大約33秒!而且,如果我寫入內存流,情況也類似。 (編輯:當我在壓縮等級=正常的7z LZMA2壓縮文件上運行時,它仍然需要9秒)

當我在實際的7zip應用程序中打開相同的壓縮文件並從那裏提取相同的文件,只需要大約2-3秒。我認爲這是一種多核(7zip)與單核(SharpCompress可能?)的事情,但我沒有注意到在使用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; 
    } 

更新:對於一個臨時的解決方案,我現在包括來自7zip的SDK的7zr.exe在我的應用程序中,並在一個新的進程中運行它以提取單個文件,將進程的輸出讀入二進制流。 與SharpCompress的約33秒相比,它的工作時間約爲3秒。適用於現在,但那種難看..所以仍然好奇,爲什麼SharpCompress似乎是如此緩慢有

回答

1

此行是問題

foreach (var entry in archive.Entries) 

問題描述here(即,如果有100個文件,第一個文件解壓100次,第二個文件解壓99次,等等)

你需要使用reader(只向前)。請參閱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 }); 
} 

它會快得多。