10

Which one does work better or is more correct? Is it better to create an object from StreamWriterclass and use it frequently in a method and finally dispose it? or is it better to use an object from StringBuilder then create an object from StreamWriter and immediately dispose it?

1)

var Write = new StreamWriter(string.Format("{0}{1}{2}", Environment.CurrentDirectory, Path.DirectorySeparatorChar, "Dummy.txt"));
for (int i = 0; i < 100; i++)
{
    //Do something include calculation 
    Write.WriteLine(something);
}
Write.Flush();
Write.Dispose();

2)

var Str = new StringBuilder();
for (int i = 0; i <     100; i++)
{
    //Do something include calculation 
    Str.AppendLine(something);
}
var Write = new StreamWriter(string.Format("{0}{1}{2}", Environment.CurrentDirectory, Path.DirectorySeparatorChar, "Dummy.txt"));
Write.Write(Str);
Write.Flush();
Write.Dispose();
Mohammad
  • 571
  • 1
  • 8
  • 24
  • 8
    Don't use `string.Format` on paths, rather use `Path.Combine(Environment.CurrentDirectory, "Dummy.txt")`. – Alxandr Aug 01 '13 at 08:11
  • 3
    for immediate `Disposal` try researching how to use the `using(){}` structure – MethodMan Aug 01 '13 at 08:13
  • use a 'using' block with streamWriters: http://stackoverflow.com/questions/212198/what-is-the-c-sharp-using-block-and-why-should-i-use-it – 5uperdan Aug 01 '13 at 08:13
  • Thank you for reply. Sometimes when the program try to write output file this error has raised "Attempted to read or write protected memory. This is often an indication that other memory has be" and I thought it may be depends on method of writing outputs. Otherwise it should be a hard disk problem. – Mohammad Aug 01 '13 at 09:04

2 Answers2

11

Streamwriter potentially uses more IO operations, but less memory. StringBuilder needs to buffer everything in memory. That may or may not be a problem.

What's more of a problem is that you're not using a using statement or try/finally, and that you're using string.Format.

I would suggest:

// Note the more conventional variable names, too...
string file = Path.Combine(Environment.CurrentDirectory, "Dummy.txt");
using (var writer = File.CreateText(file))
{
    for (int i = 0; i < 100; i++)
    {
        writer.WriteLine(...);
    }
}

Additionally, if what you're writing is naturally expressed as a LINQ query (or any other IEnumerable<string>) you can just use File.WriteAllLines:

var query = ...; // Something returning an IEnumerable<string>
var file = Path.Combine(Environment.CurrentDirectory, "Dummy.txt");
File.WriteAllLines(file, query);
Artur INTECH
  • 6,024
  • 2
  • 37
  • 34
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

It really depends on the context of your application. For example, if you have other programs listening to what comes out of that stream, and they can deal with the data a token at a time, then it's obviously preferable to go with the first approach.

That said, if you're just writing things out to a text file for storage, it will probably be worth going for the second option. I think the second option would probably run quite quickly, given that StringBuilder is pretty quick, and you're only performing one write operation, as opposed to the first option, where you're continually creating a new object for each write.

christopher
  • 26,815
  • 5
  • 55
  • 89