5

例子:

  1. 如果我读取一个文件并通过 .NET Streams 将其复制到另一个文件中,文件的总大小会随时占用内存吗?还是字节一使用就被丢弃?
  2. 如果天真的方法不能节省内存,缓冲流会这样做吗?
4

4 回答 4

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。

编辑:正如评论中所指出的,流也可能有自己的缓冲区,但关键是您仍然可以传输一个非常大的文件而不会耗尽内存。

于 2009-02-26T19:08:30.620 回答
3

如果你调用类似ReadToEnd()then yes 的方法,文件的内容将被加载到内存中。您猜对了,使用缓冲区是确保在任何给定时间仅将文件数据的一部分加载到内存中的适当方法。

于 2009-02-26T19:10:21.270 回答
2

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

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

FileStream 类使用一个内部缓冲区,其大小可以在构造函数重载中指定,默认为 0x1000 字节(可能取决于实现 - 该值是通过使用 Lutz Reflector 检查 FileStream 类获得的)。

于 2009-02-26T19:13:35.383 回答
1

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

于 2009-02-26T19:20:48.377 回答