将 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软件等打开