2016-10-27 9 views
4

Zip 아카이브에서 스트림을 집계하는 데 사용하는 함수가 있습니다.Zip 내의 Zip이 문서화되지 않은 System.IO.Compression.SubReadStream에 열립니다.

private void ExtractMiscellaneousFiles() 
{ 
    foreach (var miscellaneousFileName in _fileData.MiscellaneousFileNames) 
    { 
     var fileEntry = _archive.GetEntry(miscellaneousFileName); 
     if (fileEntry == null) 
     { 
      throw new ZipArchiveMissingFileException("Couldn't find " + miscellaneousFileName); 
     } 

     var stream = fileEntry.Open(); 
     OtherFileStreams.Add(miscellaneousFileName, (DeflateStream) stream); 
    } 
} 

대부분의 경우에 잘 작동합니다.

System.InvalidCastException : 나는 지퍼 내 우편이있는 경우 그러나, 나는 DeflateStream에 스트림을 주조상의 excpetion를 얻을 입력 유형 'System.IO.Compression.SubReadStream'의 개체를 캐스팅 할 수 없습니다 'System.IO.Compression.DeflateStream'.

SubReadStream에 대한 Microsoft 설명서를 찾을 수 없습니다. 내 우편 번호는 DeflateStream입니다. 이것이 가능한가? 그렇다면 어떻게?

여전히

성공하지 UPDATE. 나는 다음과 같은 코드를 사용하여 스트림을 복사 선샤인의 제안 @ 시도 :

private void ExtractMiscellaneousFiles() 
{ 
    _logger.Log("Extracting misc files..."); 

    foreach (var miscellaneousFileName in _fileData.MiscellaneousFileNames) 
    { 
     _logger.Log($"Opening misc file stream for {miscellaneousFileName}"); 

     var fileEntry = _archive.GetEntry(miscellaneousFileName); 
     if (fileEntry == null) 
     { 
      throw new ZipArchiveMissingFileException("Couldn't find " + miscellaneousFileName); 
     } 

     var openStream = fileEntry.Open(); 
     var deflateStream = openStream; 
     if (!(deflateStream is DeflateStream)) 
     { 
      var memoryStream = new MemoryStream(); 
      deflateStream.CopyTo(memoryStream); 
      memoryStream.Position = 0; 
      deflateStream = new DeflateStream(memoryStream, CompressionLevel.NoCompression, true); 
     } 
     OtherFileStreams.Add(miscellaneousFileName, (DeflateStream)deflateStream); 
    } 
} 

그러나 나는

System.NotSupportedException을 얻을 : 스트림이 읽기를 지원하지 않습니다.

나는 deflateStream.CanRead을 검사했다.

이 문제는 zip뿐만 아니라 압축되지 않은 파일 (예 : 너무 작기 때문에)에서도 발생합니다. 확실히 이것을 처리 할 방법이 있습니다. 분명히 누군가가 전에 이것을 경험했습니다. 나는이 질문에 현상금을 열어두고있다.

@Quantic 덕분에 SubReadStream.NET source입니다.

+0

'_archive'의 유형은 무엇입니까? – Quantic

+0

'System.IO.Compression.ZipArchive'. 감사. –

+0

.NET 코어 여야 함 : https://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/System.IO.Compression/src/System/IO/Compression/ZipCustomStreams.cs – Quantic

답변

3

ZipArchiveEntry.Open()의 반환 형식은 Stream입니다. 추상적 인 유형은 실제로는 DeflateStream (행복 할거야), SubReadStream (부두) 또는 WrappedStream (부두) 일 수 있습니다. 그들이 언젠가 수업을 향상시키고 ZopfliStream (부)을 사용하기로 결심한다면 당신도 될 수 있습니다. 일시적인 해결책은 좋지 않습니다. 압축되지 않은 데이터를 압축하려고합니다 (부).

너무 많은 boos.

오직 해결 방법은 OtherFileStreams 회원의 유형을 변경하는 것입니다. 우리는 그것을 볼 수 없으며 냄새는 List<DeflateStream>입니다. List<Stream>이어야합니다.

+0

'DeflateStream' 대신'MemoryStream'을 사용하여 해결했습니다. 더 높은 단계에서 푸는 것에 감사드립니다. –

1

다른 zip 안에 zip 파일을 저장할 때처럼 zip을 압축하지는 않지만 zip의 내용을 나머지 파일과 함께 표시합니다. 일부 정보는 이러한 항목이 sub의 일부임을 나타냅니다. 압축 파일. 이미 압축 된 것에 압축을 적용하는 것은 시간 낭비이기 때문에 어떤 의미가 있습니다.

이 zip 파일은 아카이브에 CompressionMethodValues.Stored으로 표시되어 .NET에서 DeflateStream으로 래핑하는 대신 원본 스트림을 반환합니다. 여기

출처 : 그것은 DeflateStream가 아니라면 (당신이 내 파일에 관심이 있다면) https://github.com/dotnet/corefx/blob/master/src/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs#L670

당신은

var stream = entry.Open(); 
if (!(stream is DeflateStream)) 
{ 
    var subArchive = new ZipArchive(stream); 
} 

하는 ZipArchive로 스트림을 전달할 수 또는 당신이 스트림을 복사 할 수 있습니다 FileStream (디스크에 저장하려는 경우)

var stream = entry.Open(); 
if (!(stream is DeflateStream)) 
{ 
    var fs = File.Create(Path.GetTempFileName()); 
    stream.CopyTo(fs); 
    fs.Close(); 
} 

또는 사용하고자하는 스트림에 복사하십시오.

참고 : 이것은 .NET 4에서도 마찬가지입니다.6 동작