StringWriter
和StringBuilder
有什么区别?我应该何时使用它们中的哪一个?
StringWriter
和StringBuilder
有什么区别?我应该何时使用它们中的哪一个?
那么为什么他们没有直接让StringBuilder
实现TextWriter
呢?这是一个灰色地带,因为接口背后的意图并不总是一眼就能看清。
TextWriter
几乎是接受字符流的接口。但它有一个额外的复杂之处:一个名为Encoding的属性。这意味着TextWriter
是一个接受字符流的接口并将其转换为字节的接口。
在StringWriter
中,这是一个无用的遗物,因为它不执行编码。documentation表示:
但这不对,因为我们无法指定对于某些 XML 场景,需要写入一个包含 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"?>
utf-16
头的utf-8
文件。StreamWriter
,并使用文件路径或FileStream
进行构造,或者如果您想检查数据,则使用MemoryStream
以获取字节数组。所有这些组合都可以确保编码为字节和标头生成由您的StreamWriter
中的相同Encoding
值引导。
Encoding
属性的目的是允许字符流的生成器将关于编码的准确信息包含到字符流本身中(例如在XML示例中;其他示例包括电子邮件标题等)。StringWriter
,内容生成和编码之间的链接被断开,因此这种自动机制停止工作并变得潜在错误。
然而,StringWriter
是一个有用的适配器,但您需要小心使用,即您应该理解您的内容生成代码不应依赖于Encoding
属性的无意义值。但这种警告通常与适配器模式相关联。这通常是一种hack,允许您将类似方形但几乎是圆形的钉子放入圆洞中。
StringWriter
继承自TextWriter
,允许各种类在不考虑数据流入处的情况下写文本。对于StringWriter
来说,输出只是进入内存中。如果您调用需要TextWriter
的API,但只想在内存中构建结果,则可以使用此功能。
StringBuilder
实质上是一个缓冲区,允许您对“逻辑字符串”执行多个操作(通常是追加),而无需每次创建新的字符串对象。您可以使用此功能来通过多个操作构建字符串。
在之前的(好)回答的基础上,StringWriter
实际上比 StringBuilder
更加多用途,提供了许多重载函数。
例如:
虽然 StringBuilder
仅接受字符串或无内容的参数作为 AppendLine
方法的输入。
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();
虽然不是生死攸关的事情,但仍然有所不同。
StringBuilder
类基本上是一个可变字符串,它是一个帮助类,用于构建不可变字符串。在此基础上,StringWriter
提供了更多方便的字符串格式化函数。
StringBuilder
用于大量字符串拼接。据我所知,对于超过5个字符串,它比 String.Concat()
更有效。此外,它还可以与特定格式一起使用(.AppendFormat()
)。
StringBuilder
和 StringReader
在不同的情况下用于提高性能。
使用 StringBuilder
来提高字符串操作的性能,例如连接字符串、重复修改字符串。
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
来解析大量文本的分行,并在处理数据时最小化内存使用。请参见下一个示例,其中StringReader
上的ReadLine
方法只是从当前位置开始扫描下一个换行符,然后基于字段字符串返回一个子字符串。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);
}
}
StringWriter
而不是StringReader
。 - Zev Spitz
StringWriter
类型,它使用不同的编码方式。 - ejohnson