将 7z 文件视为 .NET 流

Posted

技术标签:

【中文标题】将 7z 文件视为 .NET 流【英文标题】:Treating 7z files as .NET streams 【发布时间】:2011-04-12 06:38:29 【问题描述】:

我想链接多个流操作(例如下载文件、即时解压缩以及在没有任何临时文件的情况下处理数据)。文件为 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 文件中不可搜索的流。仍在寻找 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;
    

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

我不确定我理解你所说的单词/行边界是什么意思。 CompressedFileStream 对象在 SevenZip 从流中接收文件头时返回,而不是在获取整个文件之后。读取解压缩文件的数据也会导致源流前进。

以上是关于将 7z 文件视为 .NET 流的主要内容,如果未能解决你的问题,请参考以下文章

将7z分卷合并成一个7z文件,然后就可以使用7z或rar软件等打开

将7z分卷合并成一个7z文件,然后就可以使用7z或rar软件等打开

linux 文件后缀.7z 怎么解压

7z文件格式及其源码linux/windows编译

如何用WinRAR解压缩7z分卷文件

如何用WinRAR解压缩7z分卷文件