C#中的流重用

我一直在玩我认为简单的想法。 我希望能够从某个地方(网站,文件系统,ftp)读取文件,对其执行一些操作(压缩,加密等),然后将其保存在某个地方(某处可能是文件系统,ftp或其他) 。 这是一个基本的管道设计。 我想要做的是读入文件并将其放入MemoryStream,然后对MemoryStream中的数据执行操作,然后将该数据保存在MemoryStream中的某处。 我以为我可以使用相同的Stream来做到这一点,但遇到了几个问题:

  1. 每次我使用StreamWriter或StreamReader时,我需要关闭它并关闭流,以便我不能再使用它了。 这似乎必须有一些方法来解决这个问题。
  2. 其中一些文件可能很大,所以如果我尝试一次读取整个内容,我可能会耗尽内存。

我希望能够将每个步骤作为单独的线程启动,并在流上有数据时立即开始压缩步骤,然后一旦压缩在流上有一些压缩数据,我就可以启动保存它(例如)。 使用C#Streams可以轻松实现这样的function吗? 有人想过如何做到最好吗?

谢谢,

麦克风

使用辅助方法来驱动流式传输:

static public void StreamCopy(Stream source, Stream target) { byte[] buffer = new byte[8 * 1024]; int size; do { size = source.Read(buffer, 0, 8 * 1024); target.Write(buffer, 0, size); } while (size > 0); } 

您可以轻松组合您需要的任何内容:

 using (FileStream iFile = new FileStream(...)) using (FileStream oFile = new FileStream(...)) using (DeflateStream oZip = new DeflateStream(outFile, CompressionMode.Compress)) StreamCopy(iFile, oZip); 

根据您实际尝试的操作,您可以以不同方式链接流。 这也使用相对较少的内存,因为只有正在操作的数据在内存中。

StreamReader / StreamWriter 应该被设计为关闭它们的底层流 – 这在BCL中是一个可怕的错误。 但他们这样做,他们不会被改变(因为向后兼容),所以我们坚持这个API的灾难。

但是,如果你想使用StreamReader / Writer但是之后保持Stream打开,那么有一些完善的解决方法。

  • 对于StreamReader:不要处理StreamReader。 就这么简单。 让StreamReader在没有调用Dispose的情况下继续下去是无害的。 唯一的影响是你的Stream不会过早关闭,这实际上是一个加号。
  • 对于StreamWriter:可能存在缓冲数据,因此您无法放弃它。 您必须调用Flush,以确保缓冲的数据写入Stream。 然后你可以让StreamWriter去。 (基本上,你把一个Flush放在你通常放置Dispose的地方。)

除非你在比你的硬盘更大的数据流中阅读,否则我认为你的内存不足:

http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx