2009-02-26 30 views
5

例子:.NET流是否节省内存?

  1. 如果我读一个文件,并将其复制到通过.NET流的另一个文件将文件的总大小占据在任何时刻的记忆?或者这些字节一旦被使用就会被丢弃?
  2. 如果天真的方法不会节省内存缓冲流会做到这一点?
+0

伟大的问题! :) – overslacked 2009-02-26 19:07:04

回答

13

如果您流式复制,即读取缓冲区,写入缓冲区,读取缓冲区,写入缓冲区等,直到数据用完为止,它只会占用与缓冲区大小相同的内存。我希望File.Copy能够做到这一点(不可否认,在本机Windows代码中)。

如果你想自己做,使用这样的:

public void CopyData(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[32 * 1024]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

这将只需要32K但是大的流。

编辑:正如注释中指出的那样,这些流可能也有自己的缓冲区,但重点是您仍然可以传输非常大的文件而不会耗尽内存。

+0

... +流使用的任何内部缓冲区的大小(FileStream使用内部缓冲区,其大小默认为4K) – Joe 2009-02-26 19:17:12

+0

.NET FileStreams有其自己的内部缓冲区。因此,使用FileStreams的上述代码可能需要略多于32K的内存(无论FileStream内部缓冲区的大小是多少)。但是在任何情况下,这种技术都会使用恒定数量的内存。 – 2009-02-26 19:21:09

3

如果你打电话像ReadToEnd()那么是的,文件的内容将被加载到内存中。在猜测使用缓冲区是确保在任何给定时间只有文件数据的一个子集被加载到内存中的适当方法时,你是正确的。

2

不,整个文件不会被加载到内存中。

内存占用将取决于您用于读取和写入的缓冲区的大小以及流所维护的任何内部缓冲区。

FileStream类使用内部缓冲区,其大小可以在构造函数过载中指定,其默认值为0x1000字节(可能与实现有关 - 通过使用Lutz Reflector检查FileStream类获得此值)。

1

这真的取决于你的方法。如果您使用流作为ReadToEnd()的临时端点,则可以将整个文件加载到内存中。相反,如果您正在缓冲,则不会在缓冲区大小上使用更多的开销。

相关问题