Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream StringBuilder to file

I need to create a large text document. I currently use StringBuilder to make the document and then call File.WriteallText(filename,sb.ToString). Unfortunately, this is now starting to throw out of memory exceptions.

Is there a better way to stream a StringBuilder to file or is there some other technique I should be using?

like image 258
GreyCloud Avatar asked Nov 04 '11 10:11

GreyCloud


3 Answers

Instead of using StringBuilder, try using TextWriter (which has a broadly similar API, but which can write to a number of underlying destinations, including files) - i.e.

using(TextWriter writer = File.CreateText(path))
{
    // loop etc
    writer.Write(...);
}

More generally, it is worth separating the code that knows about files from the code that knows about how to write the data, i.e.

using(var writer = File.CreateText(path))
{
    Serialize(writer);
}
...
void Serialize(TextWriter writer)
{
    ...
}

this makes it easier to write to different targets. For example, you can now do in-memory too:

var sw = new StringWriter();
Serialize(sw);
string text = sw.ToString();

The point being: your Serialize code didn't need to change to accomodate a different target. This could also be writing directly to a network, or writing through a compression/encryption stream. Very versatile.

like image 191
Marc Gravell Avatar answered Oct 21 '22 13:10

Marc Gravell


Just use a StreamWriter that writes to a FileStream:

using (StreamWriter writer = new StreamWriter("filename.txt")) {
  ...
}

This will of course mean that you can't change the text that is already written, like you can do in a StringBuilder, but I assume that you are not using that anyway.

like image 44
Guffa Avatar answered Oct 21 '22 13:10

Guffa


Why not streaming directly into the stream? You could use the TextWriter.

like image 1
Simon Avatar answered Oct 21 '22 15:10

Simon