zip 内的 Zip 打开未记录的 System.IO.Compression.SubReadStream

Sco*_*y H 5 c# unzip stream deflatestream .net-core

我有一个用于聚合 zip 存档中的流的函数。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下效果很好。但是,如果我在 zip 中包含 zip,则将流转换为 a 时会出现异常DeflateStream

System.InvalidCastException:无法将类型“System.IO.Compression.SubReadStream”的对象强制转换为类型“System.IO.Compression.DeflateStream”。

我无法找到SubReadStream. 我希望我的 zip 内的 zip 为DeflateStream. 这可能吗?如果是这样怎么办?

更新

仍然没有成功。我尝试了@Sunshine的建议,使用以下代码复制流:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到一个

System.NotSupportedException:Stream不支持读取。

我检查了一下deflateStream.CanRead,确实如此。

我发现这种情况不仅发生在 zip 上,而且发生在 zip 中但未压缩的文件上(例如,因为太小)。当然有办法解决这个问题;肯定有人以前遇到过这种情况。我正在针对这个问题开悬赏。

感谢@Quantic,这是.NET 源代码。SubReadStream

Han*_*ant 6

ZipArchiveEntry.Open() 的返回类型是Stream。一个抽象类型,实际上它可以是 DeflateStream (你会很高兴)、SubReadStream (boo) 或 WrappedStream (boo)。如果有一天他们决定改进课程并使用 ZopfliStream(嘘),那你就惨了。解决方法不好,您正在尝试缩小未压缩的数据(嘘)。

嘘声太多了。

唯一好的解决方案是更改会员的类型OtherFileStreams。我们看不到它,闻起来像List<DeflateStream>。它需要是一个List<Stream>.