StreamReader受到的内存影响有多大?

7

当我使用以下代码中的StreamReader时,会影响多少内存?我假设由于每行都被读入到一个变量 'line' 中,只有该行保留在内存中,这总体上是一件好事。 我的目的是在阅读包含数千行的非常大的文件时不要过分负担内存。 如有疑问,请澄清。

string line = string.Empty;
using(StreamReader Reader = new StreamReader(@"C:\Users\UK\Panfile.txt"))
{
    while((line = Reader.ReadLine())!= null)
    {
        //other code to process the line now being read.
    }
Reader.Close(); Reader.Dispose();
}

作为一个无关紧要的快速评论,您不需要调用 Close 和 Dispose,因为您已经将 StreamReader 包装在 using 语句中。 - mbrdev
我对内存消耗的细节不是很确定。但是,我确信它取决于您尝试通过StreamReader读取的文件大小。因此,由于每个文件都不同,您可以预期每个文件的内存使用情况也会不同。 - Benjamin
@Benjamin,你能否更清楚地表达你的观点?我的文件可能包含数十万行。由于只有一行被保留在内存中,文件大小会如何影响内存?我无法理解。 - Unnikrishnan
感谢您对Reader.Close()和Dispose()的评论。 - Unnikrishnan
1
@Unnikrishnan,StreamReaders ReadLine会逐行读取所有行,直到没有更多行可读。当您遍历大量数据时,它将消耗更多的内存。 我强烈建议您阅读文章,了解在C#中读取和处理文本文件的最快方法。 - Benjamin
我访问了这个网站。我一定会耐心阅读它。谢谢@Benjamin。 - Unnikrishnan
2个回答

13
一个StreamReader会在调用之间使用byteBuffer.Length内存。如果您没有指定默认值,它将使用1024字节。它还会分配一个大小为encoding.GetMaxCharCount(bufferSize);char[] charBuffer,每个元素在数组中分配两个字节。

如果您没有传入一个Stream对象并让它生成自己的FileStream,它将使用默认的文件流缓冲区4096

ReadLine调用本身将在内部分配一个StringBuilder,然后将数据读入byteBuffer,接着解码这些字节并将其存储在charBuffer中,然后将字符从charBuffer复制到StringBuilder中,最后通过.ToString()调用将其返回给您。

因此,总之,new StreamReader(@"C:\Users\UK\Panfile.txt")在休息时,它将分配1024 + (1025 * 2) + 40961字节的内存(总共5120字节),并且在ReadLine调用期间,它将最多再分配line.Length * 2 + StringBuilderOverhead + line.Length * 22字节。您看到的*2是因为每个char占用两个字节。


1:byteBuffer + charBuffer + FileStream缓冲区
2:StringBuilder 内部的 char[] 数组 + 字符串构建器缓冲区中的任何额外空间 + 调用 .ToString() 方法返回的字符串。

(注:本翻译保留了原文中的HTML标签)

非常感谢您,@Scott Chamberlain。非常感谢。 - Unnikrishnan
这是一个很好的回答!你能提供一些来源吗? - BorisD

4

该方法每次只会在内存中保留一行,因此非常适合处理大文件而不会占用大量内存。


哦。谢谢@mbrdev你的回答。太好了。 - Unnikrishnan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接