1
\$\begingroup\$

Option 1 - nice and simple

private void GetFileReady()
{
    private StringBuilder fileContents = new StringBuilder();
    using (var sr = new StreamReader("C:\A big file.txt"))
    {
        fileContents.Append(sr.ReadToEnd());              
    }
}

Option 2 - less simple

private void GetFileReady2()
{
   private StringBuilder fileContents = new StringBuilder();
   const int bufferSize = 1024;
   var buffer = new Char[bufferSize];
   var count = bufferSize;

   using (var sr = new StreamReader("C:\A big file.txt"))
   {                
       while (count > 0)
       {
           count = sr.Read(buffer, 0, bufferSize);
           fileContents.Append(buffer, 0, count);
       }
   }
}

Would option 2 be better for something esoteric like memory allocation?

\$\endgroup\$
10
\$\begingroup\$

Is the goal to get a string containing the content of the file? or to add the content of a file to an existing StringBuilder?

if it's the former then Option 1 can drop the string builder altogether ... or better yet.

string value = File.ReadAllText("C:\A big file.txt");

if it's the latter then you might want to think about using StringBuilder.EnsureCapacity() to avoid the overhead of resizing the buffer more then it needs to.

\$\endgroup\$
  • \$\begingroup\$ cool, I wasn't aware of EnsureCapacity. I'll use that to size the stringbuilder from FileInfo \$\endgroup\$ – Rob Feb 28 '11 at 15:08
2
\$\begingroup\$

I don't think there's a significant difference between your two options when it comes to memory allocations. In both cases, you're reading the entire file into memory, which trumps any minor differences that might exist in the number of objects allocated by the two options. (Though both options are also immediately discarding those contents since they are only stored in local variables, but I'm assuming that this is just a highly simplified example.)

If you're concerned about memory consumption when using a big file, you need to not read in the entire file all at once. Instead, you should load chunks out of the file as needed by your application, and discard them when no longer needed so the memory can be reclaimed.

\$\endgroup\$
  • \$\begingroup\$ This answer is incorrect: the first implementation requires double the file size temporarily during fileContents.Append() before the result of sr.ReadToEnd() can be discarded, while the second only requires 2kB overhead for the read buffer. Apologies for the comment on a seven-year old answer, but this does still come up on google! \$\endgroup\$ – Simon Buchan Nov 12 '18 at 0:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.