StringWriter或StringBuilder

StringWriterStringBuilder什么区别,什么时候应该使用一个或另一个?

我不认为任何现有的答案真的回答了这个问题。 这两个类之间的实际关系就是适配器模式的一个例子。

StringWriter通过转发到存储在字段中的StringBuilder实例来实现其所有Write...方法。 这不仅仅是一个内部细节,因为StringWriter有一个公共方法GetStringBuilder ,它返回内部的string生成器,也是一个构造函数 ,允许你传入一个现有的StringBuilder

所以StringWriter是一个适配器,它允许StringBuilder作为一个代码来使用TextWriter 。 就基本行为而言,他们之间显然没有什么可以select的……除非你能测量转发调用的开销,在这种情况下, StringWriter稍微慢一些,但这似乎不太可能是重要的。

那么为什么他们不让StringBuilder直接实现TextWriter呢? 这是一个灰色地带,因为界面背后的意图乍一看并不一定总是清晰的。

TextWriter 几乎是接受字符stream的接口。 但它有一个额外的皱纹:一个称为Encoding的属性。 这意味着TextWriter是一个接受一个字符stream并将它们转换为字节的接口

StringWriter这是一个无用的痕迹,因为它不执行编码。 该文件说:

此属性对于某些必须写入包含StringWriter使用的编码的XML场景是必需的。 这允许XML代码使用任意的StringWriter并生成正确的XML标题。

但是这是不对的,因为我们没有办法指定StringWriterEncoding值。 该属性的值始终为UnicodeEncoding 。 因此,任何检查这个属性来构build一个XML头的代码总是会说utf-16 。 例如:

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

这会产生标题:

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

如果使用File.WriteAllText将XMLstring写入文件会怎么样? 默认情况下,你会有一个utf-8文件的utf-8文件。

在这种情况下,使用StreamWriter会比较安全,并使用文件path或FileStream构造它,或者如果要检查数据,则使用MemoryStream并获取字节数组 。 所有这些组合都将确保编码字节和标题生成在StreamWriter由相同的Encoding值引导。

Encoding属性的目的是允许字符stream生成器将关于编码的准确信息包含到字符stream本身中(例如在XML示例中;其他示例包括电子邮件标题等)。

但是,通过引入StringWriter ,内容生成和编码之间的链接被破坏,所以这种自动机制停止工作,并可能出错。

不过,如果你小心, StringWriter是一个有用的适配器,也就是说你明白你的内容生成代码不应该依赖Encoding属性的无意义的值。 但是这种警告通常与适配器模式有关。 这通常是一种方法,可以让你将一个几乎是圆形的钉子装进一个圆孔中。

StringWriter派生自TextWriter ,它允许不同的类写文本,而不必关心它发生的地方。 在StringWriter的情况下,输出只是进入内存。 如果您要调用需要TextWriter的API,但只想在内存中创build结果,则可以使用此方法。

StringBuilder本质上是一个缓冲区,它允许你执行多个操作(通常追加)到一个“逻辑string”,而不是每次创build一个新的string对象。 你可以用这个在多个操作中构造一个string。

StringBuilder类基本上是一个可变string,一个帮助类来构造一个不可变的string。 StringWriter构build在顶部,为string格式添加更多便利function。

一个StringWriter被用来写文本 一份文件 内存和一个StringBuilder被用来以一种有效的方式将string追加到一起。

基于以前的(良好)答案,StringWriter实际上比StringBuilderfunction更多,提供了很多重载。

例如:

虽然Stringbuilder只接受一个string或没有任何附录

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

StringWriter可以直接使用string格式

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

使用StringBuilder必须做到这一点(或使用string.Format或$“”)

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

不做或死的东西,但仍然是一个区别

StringBuilder用于批量string连接。 对于超过5个string更有效,据我所知,然后String.Concat() 。 也可以使用特定的格式( .AppendFormat()

StringBuilderStringReader用于改善不同情况下的性能。
使用 StringBuilder来提高string操作的性能,例如连接,重复修改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()); 

使用 StringReader分析大量的文本,并在处理数据时尽量减less内存占用。 查看下一个示例,其中StringReader上的ReadLine方法只是扫描从当前位置开始的下一个换行符,然后根据字段string返回一个sbstring。

 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); } }