StringWriter和StringBuilder之间有什么区别?什么时候应该使用其中一个?
发布于 2012-06-15 18:29:29
我认为现有的答案中没有任何一个真正回答了这个问题。这两个类之间的实际关系是the adapter pattern的一个示例。
StringWriter通过转发到存储在字段中的StringBuilder实例来实现其所有Write...方法。这不仅仅是一个内部细节,因为StringWriter有一个返回内部字符串构建器的公共方法GetStringBuilder,还有一个允许您传入现有StringBuilder的a constructor。
因此,StringWriter是一个适配器,它允许希望与TextWriter一起工作的代码将StringBuilder用作目标。就基本行为而言,它们之间显然没有什么可选择的……除非您可以测量转发调用的开销,在这种情况下,StringWriter会稍微慢一些,但这似乎不太可能很重要。
那么为什么他们不让StringBuilder直接实现TextWriter呢?这是一个灰色区域,因为界面背后的意图不一定一目了然。
TextWriter非常接近于接受字符流的东西的接口。但它还有一个额外的问题:一个名为Encoding的属性。这意味着TextWriter是接受字符流并将其转换为字节的接口。
这在StringWriter中是一个无用的遗迹,因为它不执行编码。documentation说:
对于某些必须写入包含StringWriter使用的编码的标头的
方案,此属性是必需的。这允许XML代码使用任意的StringWriter并生成正确的XML头。
但这不可能是正确的,因为我们无法为StringWriter指定Encoding的值。该属性的值始终为UnicodeEncoding。因此,任何检查此属性以构建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将XML字符串写入文件,情况会怎样呢?默认情况下,您将拥有一个带有utf-16头的utf-8文件。
在这种情况下,使用StreamWriter更安全,并使用文件路径或FileStream构造它,或者如果您想检查数据,则使用MemoryStream或obtain an array of bytes。所有这些组合将确保对字节的编码和头生成由StreamWriter中相同的Encoding值指导。
Encoding属性的目的是允许字符流的生成器将有关编码的准确信息包含到字符流本身中(例如,在XML示例中;其他示例包括电子邮件标头等)。
但是通过引入StringWriter,内容生成和编码之间的联系被打破了,因此这样的自动机制停止工作,并且可能变得容易出错。
然而,如果你仔细的话,StringWriter是一个有用的适配器,也就是说,你明白你的内容生成代码不应该依赖于Encoding属性的无意义的值。但这种警告通常与适配器模式相关。这通常是一种技巧,可以让你把一个方形但几乎是圆形的钉子装进一个圆孔中。
发布于 2009-03-02 13:13:32
StringWriter是从TextWriter派生出来的,它允许不同的类编写文本,而无需关心文本的去向。在使用StringWriter的情况下,输出只是进入内存。如果你正在调用一个需要TextWriter的应用程序接口,但是你只想在内存中建立结果,那么你可以使用它。
StringBuilder本质上是一个缓冲区,它允许您对“逻辑字符串”执行多个操作(通常是追加操作),而无需每次都创建新的字符串对象。您可以使用它在多个操作中构造一个字符串。
发布于 2015-07-22 17:49:39
在前面(好的)答案的基础上,StringWriter实际上比StringBuilder更通用,提供了大量的重载。
例如:
而对于AppendLine,StringBuilder只接受字符串或不接受任何内容
StringBuilder sb = new StringBuilder();
sb.AppendLine("A string");StringWriter可以直接接受字符串格式
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();不是做或死的东西,但仍然是不同的。
https://stackoverflow.com/questions/602279
复制相似问题