C# C语言中的流重用#
我一直在玩弄我认为很简单的想法。我希望能够从某处(网站、文件系统、ftp)读入文件,对其执行一些操作(压缩、加密等),然后将其保存到某处(某处可能是文件系统、ftp或其他)。这是一个基本的管道设计。我想做的是读入文件并将其放入MemoryStream,然后对MemoryStream中的数据执行操作,然后将该数据保存在MemoryStream中的某个位置。我想我可以使用相同的流来完成这项工作,但遇到了几个问题:C# C语言中的流重用#,c#,C#,我一直在玩弄我认为很简单的想法。我希望能够从某处(网站、文件系统、ftp)读入文件,对其执行一些操作(压缩、加密等),然后将其保存到某处(某处可能是文件系统、ftp或其他)。这是一个基本的管道设计。我想做的是读入文件并将其放入MemoryStream,然后对MemoryStream中的数据执行操作,然后将该数据保存在MemoryStream中的某个位置。我想我可以使用相同的流来完成这项工作,但遇到了几个问题: 每次我使用StreamWriter或StreamReader时,我都需要关闭它,这会关
Mike使用助手方法驱动流媒体:
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,但之后要保持流的打开状态,则有一些行之有效的解决方法
- 对于StreamReader:不要处理StreamReader。就这么简单。让StreamReader离开而不调用Dispose是无害的。唯一的效果是您的流不会过早关闭,这实际上是一个加号
- 对于StreamWriter:可能存在缓冲数据,因此您不能让它离开。您必须调用Flush,以确保缓冲数据写入流。然后你就可以让StreamWriter走了。(基本上,你把一个冲水,你通常会把一个处置。)
但您可能会耗尽地址空间,这正是本文的重点。如果您确实需要使用StreamReader和StreamWriter,但必须确保基础流从不关闭,请创建一个代理流类,该类仅将每个调用传递给基础流,对Close和Dispose方法的调用除外(您可以忽略),并在将基础流传递给读写器构造函数时使用代理将其包装。然后,您可以正常使用读写器类。自.NET 4.0以来,您可以使用内置的
.CopyTo
和.copytosync
将流复制到另一个流