11

我想链接多个流操作(例如下载文件,即时解压缩,以及在没有任何临时文件的情况下处理数据)。文件为 7z 格式。有一个 LZMA SDK 可用,但迫使我创建一个外部输出流而不是一个流本身 - 换句话说,输出流必须在我可以使用它之前完全编写。SevenZipSharp 似乎也缺少此功能。

有没有人做过类似的事情?

// in pseudo-code - CompressedFileStream derives from Stream
foreach (CompressedFileStream f in SevenZip.UncompressFiles(Web.GetStreamFromWeb(url))
{
    Console.WriteLine("Processing file {0}", f.Name);
    ProcessStream( f ); // further streaming, like decoding, processing, etc
}

每个文件流的行为就像代表一个文件的一次读取流,并且在主压缩流上调用 MoveNext() 将自动使该文件无效并跳过该文件。

可以对压缩进行类似的构造。示例用法 - 对大量数据进行一些聚合 - 对于目录中的每个 7z 文件,对于内部的每个文件,对于每个文件中的每个数据行,总结一些值。

更新 2012-01-06

#ziplib (SharpZipLib) 已经完全满足了我对带有ZipInputStream类的 zip 文件的需求。这是一个示例,它将所有文件生成为给定 zip 文件中不可搜索的流。仍在寻找 7z 解决方案。

IEnumerable<Stream> UnZipStream(Stream stream)
{
    using (var zipStream = new ZipInputStream(stream))
    {
        ZipEntry entry;
        while ((entry = zipStream.GetNextEntry()) != null)
            if (entry.IsFile)
                yield return zipStream;
    }
}
4

1 回答 1

0

压缩时指定的底层算法和参数决定了使用的块的大小,并且无法确保在解码块时它们落在字/行边界。因此,您必须在处理之前完全解压缩文件。

如果没有临时文件,您要求做的事情可能是不可能的 - 它真正取决于您是否有足够的内存来通过 MemoryStream 打开解压缩文件,执行所有处理,然后将内存释放回池中。更复杂的是您可能会导致重复执行此操作的(进程内存的)碎片。

于 2011-08-29T09:25:40.283 回答