2017-04-25 16 views
0

LZMA2 압축 (압축 수준 : 울트라)으로 압축 된 7zip 아카이브가 있습니다. 아카이브에는 원래 총 크기가 661MB 인 1,749 개의 파일이 포함되어 있습니다. 압축 파일의 크기는 39MB입니다.SharpCompress 및 LZMA2 7z 아카이브 - 특정 파일을 매우 느리게 추출합니다. 왜? 대안?

이제이 아카이브에서 작은 (약 200kb의) 단일 파일을 추출하기 위해 C#을 사용하려고합니다.

비교적 빠른 IArchive ()에서 해당 IArchiveEntry를 가져오고 있지만 IArchiveEntry.WriteToFile (targetPath)을 호출하는 데는 약 33 초가 걸립니다! 그리고 마찬가지로 메모리 스트림에 쓰면 길어집니다. (편집 : 압축 수준이 정상인 7z LZMA2 압축 파일을 실행할 때 9 초 걸린다.)

실제 7zip 응용 프로그램에서 같은 아카이브를 열고 거기에서 같은 파일을 추출 할 때 약 2-3 초 정도 걸립니다. 멀티 코어 (7zip) 대 싱글 코어 (SharpCompress일까요?) 일종의 것으로 의심 스럽지만 7zip으로 압축 해제하는 동안 CPU 사용량이 눈에 띄지 않습니다. 어쩌면 눈에 띄기에는 너무 빠릅니다.

누구나 SharpCompress에서 느린 속도로 문제가 될 수 있다는 것을 알고 있습니까? 어쩌면 일부 설정이 누락되었거나 잘못된 공장 (ArchiveFactory)을 사용하고 있습니까?

그렇지 않다면 압축을 풀 때 상당히 빠를 수있는 C# 라이브러리가 있습니까?

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; 
    } 

업데이트 : 참고로

, 여기에 내가 추출 SharpCompress을 사용하고 방법의 스케치의 임시 해결책, 나는 지금 7zip과 SDK에서 7zr.exe을 포함하고있어 내 응용 프로그램에서 새 프로세스에서 실행하여 단일 파일을 추출하고 프로세스의 출력을 이진 스트림으로 읽습니다. SharpCompress에서 ~ 33 초 사이에 비해 약 3 초가 걸립니다. 지금은 작동하지만 종류의 추악한 .. 그래서 여전히 호기심 왜 SharpCompress이 라인은 문제가

답변

1

너무 느린 것 같다

foreach (var entry in archive.Entries) 

문제는 설명 here (예. 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 }); 
} 

훨씬 빠릅니다.