2010-09-14 88 views
10

我想链接多个流操作(如下载文件,动态解压缩以及处理没有任何临时文件的数据)。这些文件是7z格式。有一个LZMA SDK可用,但迫使我创建一个外部输出流,而不是一个流本身 - 换句话说,输出流将不得不完全写入,然后才能使用它。 SevenZipSharp似乎也缺少这项功能。将7z文件当作.NET流处理

有没有人做过这样的事情?

// 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()将自动失效&跳过该文件。

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

UPDATE 2012-01-06

#ziplib(SharpZipLib)已经不正是我需要的zip文件与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; 
    } 
} 

回答

0

在压缩时指定的基本算法和参数确定所使用的块的大小,并且没有办法确保你解码块,它们落入在字/行边界。所以,在处理之前你必须完全解压文件。

你所要求做的是可能不可能没有临时文件 - 它到底要看的是你是否有足够的内存,以保持解压缩文件的打开通过一个MemoryStream,执行所有的处理,然后释放内存回到游泳池。更复杂的是你可能会导致重复这样做的碎片(进程内存)。

+0

我不确定我是否明白你的意思是由单词/行的边界。压缩文件流对象在SevenZip从流接收文件头的时刻返回,而不是在获得整个文件之后。读取解压缩文件的数据也会导致源码流也向前移动。 – Yurik 2012-01-05 23:56:51