4

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

これは、ほとんどの場合にうまく機能します。ただし、zip 内に zip がある場合、ストリームを にキャストすると例外が発生しますDeflateStream

System.InvalidCastException: タイプ 'System.IO.Compression.SubReadStream' のオブジェクトをタイプ 'System.IO.Compression.DeflateStream' にキャストできません。

の Microsoft ドキュメントが見つかりませんSubReadStream。zip として 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);
    }
}

しかし、私は

System.NotSupportedException: ストリームは読み取りをサポートしていません。

調べdeflateStream.CanReadましたが本当です。

これは、zip だけでなく、zip 内にあるが圧縮されていないファイルでも発生することがわかりました (小さすぎるなどの理由で)。確かにこれに対処する方法があります。確かに誰かがこれに遭遇したことがあります。私はこの質問に報奨金を出しています。

@Quantic のおかげで、これがの.NET ソースです。SubReadStream

4

2 に答える 2

5

ZipArchiveEntry.Open() の戻り値の型は ですStream。抽象型です。実際には、DeflateStream (嬉しいです)、SubReadStream (ブー)、または WrappedStream (ブー) にすることができます。彼らがいつかクラスを改善し、ZopfliStream (ブー) を使用することを決定した場合、あなたは悲惨です。回避策は良くありません。圧縮されていないデータを圧縮しようとしています (ブー)。

ブーイングが多すぎる。

唯一の良いOtherFileStreams解決策は、メンバーのタイプを変更することです。私たちはそれを見ることができません、のようなにおいがしList<DeflateStream>ます。である必要がありますList<Stream>

于 2016-11-29T20:20:11.627 に答える