Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much memory is affected from StreamReader

Tags:

c#

When I use StreamReader as below, how much memory is affected. I presume since each line is read into a variable 'line', only that line remains in memory and that is overall a good thing. My purpose is not to burden memory too much when I read a very very large containing thousands of lines. A clarification will be appreciated.

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();
}
like image 682
Unnikrishnan Avatar asked Sep 29 '16 00:09

Unnikrishnan


People also ask

Is StreamReader thread safe?

By default, a StreamReader is not thread safe.

Do you need to close StreamReader?

No, there is no need to explicitly call reader. Close if the reading process is inside a using block.

What does StreamReader return?

C# StreamReader ReadToEnd It returns the rest of the stream as a string, from the current position to the end; if the current position is at the end of the stream, it returns an empty string. Note: This method is not suited for large files. If the file had 8 GB, it would load all the data into the memory.

What is the difference between a StreamReader and file ReadAllLines?

The StreamReader read the file line by line, it will consume less memory. Whereas, File. ReadAllLines read all lines at once and store it into string[] , it will consume more memory.


2 Answers

A StreamReader will use byteBuffer.Length of memory between calls. If you have not specified a default it uses 1024 bytes. It also allocates a char[] charBuffer of size encoding.GetMaxCharCount(bufferSize); which allocates two bytes per element in the array.

If you do not pass in a Stream object and let it generate it's own FileStream it will use a default filestream buffer of 4096.

The ReadLine call itself will allocate a StringBuilder internally and will read data into the byteBuffer then decode the bytes and store it in the charBuffer, it will then copy the chars out of the charBuffer and into the StringBuilder which then is returned to you via a .ToString() call.

So in summary, new StreamReader(@"C:\Users\UK\Panfile.txt") at rest it will will allocate 1024 + (1025 * 2) + 40961 bytes of memory (5120 total), and during the ReadLine call it will allocate at most an additional line.Length * 2 + StringBuilderOverhead + line.Length * 22. The *2's you see are for the char[] because each char takes up two bytes.


1:byteBuffer + charBuffer + the FileStream buffer
2:The char[] internal to the StringBuilder + Any slack space in the string builder buffer + the string returned by the .ToString() call.

like image 136
Scott Chamberlain Avatar answered Oct 16 '22 03:10

Scott Chamberlain


It will only hold 1 line in memory at a time so this method is perfect for processing large files without eating up lots of memory.

like image 20
mbrdev Avatar answered Oct 16 '22 05:10

mbrdev