【问题标题】:Does the .NET Streams save memory?.NET Streams 是否节省内存?
【发布时间】:2009-02-26 19:03:18
【问题描述】:

例子:

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

【问题讨论】:

    标签: .net memory stream


    【解决方案1】:

    如果您流式传输复制,即读取缓冲区、写入缓冲区、读取缓冲区、写入缓冲区等,直到数据用完,它只需要与缓冲区大小一样多的内存。我希望 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。

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

    【讨论】:

    • ... + Stream 使用的任何内部缓冲区的大小(FileStream 使用大小默认为 4K 的内部缓冲区)
    • .NET FileStreams 有自己的内部缓冲区。因此,将上述代码与 FileStreams 一起使用可能会占用略多于 32K 的内存(32K + 无论 FileStream 内部缓冲区的大小是多少)。但无论如何,这种技术使用的内存量是恒定的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 简要说明:ReadToEnd() 存在于 TextReader,而不是 Stream。
        猜你喜欢
        • 2015-12-17
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 2014-08-29
        • 2013-05-12
        相关资源
        最近更新 更多