.net StringWriter 或 StringBuilder

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/602279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:14:19  来源:igfitidea点击:

StringWriter or StringBuilder

.netstringbuilderstringwriter

提问by Daniel Earwicker

What is the difference between StringWriterand StringBuilderand when should I use one or the other?

是什么区别StringWriterStringBuilder,当我应该使用一个或其他?

回答by Daniel Earwicker

I don't think any of the existing answers really answer the question. The actual relationship between the two classes is an example of the adapter pattern.

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

StringWriterimplements all its Write...methods by forwarding on to an instance of StringBuilderthat it stores in a field. This is not merely an internal detail, because StringWriterhas a public method GetStringBuilderthat returns the internal string builder, and also a constructorthat allows you to pass in an existing StringBuilder.

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

So StringWriteris an adaptor that allows StringBuilderto be used as a target by code that expects to work with a TextWriter. In terms of basic behaviour there is clearly nothing to choose between them... unless you can measure the overhead of forwarding the calls, in which case StringWriteris slightly slower, but that seems very unlikely to be significant.

StringWriter一个适配器也是如此,它允许StringBuilder被期望使用TextWriter. 就基本行为而言,它们之间显然没有任何选择……除非您可以测量转发呼叫的开销,在这种情况下StringWriter会稍微慢一些,但这似乎不太可能是重要的。

So why didn't they make StringBuilderimplement TextWriterdirectly? This is a grey area, because the intention behind an interface is not necessarily always clear at first glance.

那么他们为什么不直接制作StringBuilder工具TextWriter呢?这是一个灰色区域,因为界面背后的意图乍一看不一定总是很清楚。

TextWriteris very nearlyan interface to something that accepts a stream of characters. But it has an additional wrinkle: a property called Encoding. This implies that TextWriteris an interface to something that accepts a stream of characters and also converts them into bytes.

TextWriter非常接近的,接受的字符流的东西接口。但它还有一个额外的问题:一个名为Encoding的属性。这意味着它TextWriter是一个接口,它接受字符流并将它们转换为字节

This is a useless vestige in StringWriterbecause it performs no encoding. The documentationsays:

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

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

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

But that can't be right, because there is no way for us to specify the value of Encodingfor StringWriter. The property always has the value UnicodeEncoding. Consequently any code that examined this property to build an XML header into would always say utf-16. For example:

但这不可能是对的,因为我们无法指定Encodingfor的值StringWriter。该属性始终具有值UnicodeEncoding。因此,任何检查此属性以将 XML 标头构建到其中的代码总是会显示utf-16. 例如:

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

That produces the header:

这会产生标题:

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

What if you used File.WriteAllTextto write your XML string to a file? By default, you'd then have a utf-8file with a utf-16header.

如果您使用File.WriteAllText将 XML 字符串写入文件会怎样?默认情况下,您将拥有一个utf-8带有utf-16标题的文件。

In such scenarios it would be safer to use StreamWriter, and construct it with a file path, or a FileStream, or if you want to examine the data then use a MemoryStreamand so obtain an array of bytes. All these combinations would ensure that the encoding to bytes and the header generation were being guided by the same Encodingvalue in your StreamWriter.

在这种情况下,使用StreamWriter并使用文件路径或 a 构造它会更安全FileStream,或者如果您想检查数据,则使用 aMemoryStream并因此获取字节数组。所有这些组合将确保编码字节,首部产生是由同一个引导Encoding你的价值StreamWriter

The aim of the Encodingproperty was to allow generators of character streams to include accurate information about the encoding into the character stream itself (such as in the XML example; other examples include email headers, and so on).

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

But by introducing StringWriter, that link between content generation and encoding is broken, and so such automatic mechanisms stop working and become potentially error prone.

但是通过引入StringWriter,内容生成和编码之间的联系被打破,因此这种自动机制停止工作并变得容易出错。

Nevertheless, StringWriteris a useful adaptor if you are careful, i.e. you understand that your content generation code should not depend on the meaningless value of the Encodingproperty. But that kind of caveat is commonly associated with the adaptor pattern. It's often a sort of hack to allow you to fit a square-ish-but-almost round peg into a round hole.

然而,StringWriter如果您小心,它是一个有用的适配器,即您了解您的内容生成代码不应依赖于无意义的Encoding属性值。但这种警告通常与适配器模式相关。它通常是一种技巧,可以让您将一个方形但几乎是圆形的钉子放入圆孔中。

回答by Jon Skeet

StringWriterderives from TextWriter, which allows various classes to write text without caring where it's going. In the case of StringWriter, the output is just into memory. You would use this if you're calling an API which needs a TextWriterbut you only want to build up results in memory.

StringWriter派生自TextWriter,它允许各种类编写文本而无需关心它的去向。在 的情况下StringWriter,输出只是进入内存。如果您正在调用需要 aTextWriter但您只想在内存中建立结果的 API,您将使用它。

StringBuilderis essentially a buffer which allows you to perform multiple operations (typically appends) to a "logical string" without creating a new string object each time. You would use this to construct a string in multiple operations.

StringBuilder本质上是一个缓冲区,它允许您对“逻辑字符串”执行多个操作(通常是追加),而无需每次都创建新的字符串对象。您将使用它在多个操作中构造一个字符串。

回答by Johan Sonesson

Building on the previous (good) answers, StringWriter is actually much more versatile than StringBuilder, providing lots of overloads.

基于之前的(好的)答案,StringWriter 实际上比 StringBuilder 更通用,提供了许多重载。

For example:

例如:

While Stringbuilder only accepts a string or nothing for Appendline

虽然 Stringbuilder 只接受一个字符串或不接受 Appendline

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

StringWriter can take a string format directly

StringWriter 可以直接取字符串格式

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

With StringBuilder one must do this (or use string.Format, or $"")

使用 StringBuilder 必须这样做(或使用 string.Format 或 $"")

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

Not do or die stuff, but still a difference

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

回答by Konrad Rudolph

The StringBuilderclass is basically a mutable string, a helper class to constructan immutable string. The StringWriteris built on top to add more convenience functions for string formatting.

StringBuilder级基本上是一个可变的字符串,一个辅助类来构建一个不可变的字符串。该StringWriter是建立在顶部增加了更多的便利功能字符串格式化。

回答by Andrew Hare

A StringWriteris used to write text to a filememory and a StringBuilderis used to append strings together in a memory-efficient manner.

AStringWriter用于将文本写入一份文件memory 和 aStringBuilder用于以节省内存的方式将字符串附加在一起。

回答by Serge Voloshenko

StringBuilderand StringReaderare used to improve performance in different situations.
UseStringBuilderto improve performance on string manipulation such as concatenation, modifying string repeatedly.

StringBuilderStringReader用于提高不同情况下的性能。
使用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());

UseStringReaderto parse a large amount of text in separate lines and minimize memory use while processing data. See next example where ReadLine method on StringReader simply scans for the next newline starting at the current postion, and then return a sbstring based on the field string.

用于StringReader在单独的行中解析大量文本并在处理数据时最大限度地减少内存使用。请参阅下一个示例,其中 StringReader 上的 ReadLine 方法仅扫描从当前位置开始的下一个换行符,然后根据字段字符串返回一个 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);
    }
}

回答by abatishchev

StringBuilderis used to mass string concatenation. It's more effective for more then 5 string, As far as i know, then String.Concat(). Also it can be used with specific format (.AppendFormat())

StringBuilder用于大量字符串连接。它对超过 5 个字符串更有效,据我所知,然后String.Concat(). 它也可以用于特定格式 ( .AppendFormat())