StringWriter or StringBuilder

What is the difference between StringWriter and StringBuilder and when should I use one or the other?

+58
stringbuilder stringwriter
Mar 02 '09 at 13:04
source share
7 answers

I do not think that any of the existing answers really answers the question. The actual relationship between the two classes is an example of an adapter pattern .

StringWriter implements all of its Write... methods by forwarding to the StringBuilder instance that it stores in the field. This is not just an internal detail, because StringWriter has a public GetStringBuilder method that returns an internal string builder, as well as a constructor that allows you to pass an existing StringBuilder .

So, StringWriter is an adapter that allows you to use StringBuilder as a target with code that expects to work with TextWriter . From the point of view of the basic behavior, there is clearly nothing to choose between them ... if you cannot measure the overhead of call forwarding, in which case the StringWriter will be a little slower, but this seems very unlikely.

So why didn’t they make StringBuilder implement TextWriter directly? This is a gray area because the intention of the interface is not always always clear at first glance.

TextWriter is almost an interface for something that accepts a character stream. But he has an extra wrinkle: a property called Encoding . This means that TextWriter is an interface to what accepts a stream of characters and also converts them to bytes.

This is a useless remainder in StringWriter because it does not perform encoding. The documentation says:

This property is necessary for some XML scripts where the header must be written with the encoding used by StringWriter. This allows the XML to consume an arbitrary StringWriter and generate the correct XML header.

But this may not be correct, because we do not need to specify the Encoding value for StringWriter . The property always has the value UnicodeEncoding . Therefore, any code that considered this property to build an XML header would always say utf-16 . For example:

 var stringWriter = new StringWriter(); using (var xmlWriter = XmlWriter.Create(stringWriter)) xDocument.WriteTo(xmlWriter); 

This creates the header:

 <?xml version="1.0" encoding="utf-16"?> 

What if you used File.WriteAllText to write your XML string to a file? By default, you will have a utf-8 file with the utf-16 header.

In such scenarios, it would be safer to use StreamWriter and build it using a file path or FileStream , or if you want to examine the data, use a MemoryStream and thus get an array of bytes . All of these combinations would ensure that byte encoding and header generation would be guided by the same Encoding value in your StreamWriter .

The purpose of the Encoding property was to allow character stream generators to include accurate encoding information in the character stream itself (for example, in the XML example, other examples include email headers, etc.)

But by introducing StringWriter , this connection between the creation and encoding of content is broken, and therefore such automatic mechanisms stop working and become potentially error prone.

Nevertheless, StringWriter is a useful adapter if you are careful, that is, understand that the code for generating your content should not depend on the meaningless value of the Encoding property. But such a caution is usually associated with the adapter template. This is often a kind of hack, allowing you to fit a square-but-almost round pin into a round hole.

+66
Jun 15 '12 at 10:29
source share

StringWriter comes from TextWriter , which allows different classes to write text without worrying about where it goes. In the case of StringWriter output goes into memory. You would use this if you are calling an API that requires a TextWriter , but you only want to create the results in memory.

StringBuilder is essentially a buffer that allows you to perform several operations (usually attached) to a “logical string” without creating a new String object each time. You should use this to build a string in several operations.

+54
Mar 02 '09 at 13:13
source share

The StringBuilder class is basically a mutable string, a helper class for constructing an immutable string. StringWriter built on top to add additional convenience features for formatting strings.

+3
Mar 02 '09 at 13:09
source share

A StringWriter used to write text to file and StringBuilder used to add strings along with memory efficiency.

+2
Mar 02 '09 at 13:07
source share

Based on the previous (good) answers, StringWriter is actually much more versatile than StringBuilder, providing many overloads.

For example:

While Stringbuilder accepts only string or nothing for appendline

 StringBuilder sb = new StringBuilder(); sb.AppendLine("A string"); 

StringWriter can accept string format directly

 StringWriter sw = new StringWriter(); sw.WriteLine("A formatted string {0}", DateTime.Now); 

Using StringBuilder you need to do this (or use string.Format or $ "")

 sb.AppendFormat("A formatted string {0}", DateTime.Now); sb.AppendLine(); 

Do not and do not die, but still the difference

+2
Jul 22 '15 at 9:49
source share

StringBuilder used to mass concatenate strings. This is more efficient for more than 5 lines, as far as I know, then String.Concat() . It can also be used with a specific format ( .AppendFormat() )

0
Mar 02 '09 at 13:07
source share

StringBuilder and StringReader are used to improve performance in different situations.
Use StringBuilder to improve performance when manipulating strings such as concatenation by repeatedly modifying a string.

 Random rnd = new Random(); StringBuilder sb = new StringBuilder(); // Generate 10 random numbers and store in sb. for (int i = 0; i < 10; i++) { sb.Append(rnd.Next().ToString("N5")); } Console.WriteLine("The original string:"); Console.WriteLine(sb.ToString()); // Decrease each number by one. for (int ctr = 0; ctr < sb.Length; ctr++) { if (Char.GetUnicodeCategory(sb[ctr]) == System.Globalization.UnicodeCategory.DecimalDigitNumber) { int number = (int)Char.GetNumericValue(sb[ctr]); number--; if (number < 0) number = 9; sb[ctr] = number.ToString()[0]; } } Console.WriteLine("\nThe new string:"); Console.WriteLine(sb.ToString()); 

Use StringReader to parse large amounts of text on separate lines and minimize memory usage during data processing. See the following example in which the ReadLine method on StringReader simply scans the next line of a new line, starting at the current position, and then returns the sbstring line based on the field string.

 using (StringReader sr = new StringReader("input.txt")) { // Loop over the lines in the string or txt file. int count = 0; string line; while((line = sr.ReadLine()) != null) { count++; Console.WriteLine("Line {0}: {1}", count, line); } } 
0
Nov 13 '16 at 1:48
source share



All Articles