35

我最近读到它StringWriterStringReader用于从StringBuilder.

好吧,当我使用StringBuilderObject 时,它看起来是一个自给自足的类。

我们有各种阅读和写作的方式,StringBuilder使用 StringBuilder.Append(),,,等等......Insert()Replace()Remove()

  1. StringWriter和的可能用途是什么StringReader,这不能单独完成StringBuilder
  2. 它们的实际用途是什么?
  3. 他们没有作为输入的可能原因是什么Stream(因为任何其他写入器和读取器都将流作为构造函数参数进行操作)但是StringBuilder
4

4 回答 4

37

StringWriter 和 StringReader 的可能用途是什么,StringBuilder 本身无法做到这一点?

StringReaderStringWriter分别来自TextReaderTextWriter。所以他们可以做什么作为一个TextReaderTextWriter实例,string或者StringBuilder不能,因为他们没有派生这些类型中的任何一个。

它们的实际用途是什么?

当您拥有/想要的是 or 时,它们允许您调用期望TextReaderor的 API 。TextWriterstringStringBuilder

他们不使用 Stream 作为输入的可能原因是什么(因为任何其他编写器和读取器都将流作为构造函数参数进行操作)而是 StringBuilder?

因为它们不适用于流;他们在strings 或StringBuilders 上工作。它们只是简单的包装类,可以为需要不同接口的 API 调整这些类型。请参阅:适配器模式

于 2010-08-03T00:38:10.763 回答
7

其他人已经说过了,但这是因为它们来自TextReader/TextWriter,可以代替它们使用。一方面,如果您只想将内容作为字符串,则使用与用于文件的相同方法输出行更有意义。如果您想要在内存中跨越多行的输出,为什么还要记住使用 StringBuilder 在每行的末尾放置“\r\n”?如果您希望代码在仅使用“\n”作为换行符的系统上运行或格式化数据怎么办?

StringBuilder sb = new StringBuilder();
// will be invalid on systems that only use \n
sb.AppendFormat("{0:yyyy-MM-dd HH:mm:ss} - Start\r\n", DateTime.Now);
// still have to add an extra parameter
sb.AppendFormat("The current time is {0:yyyy-MM-dd HH:mm:ss}{1}", DateTime.Now,
    Environment.NewLine);

StringWriter sw = new StringWriter();
// Don't have to worry about it, method name tells you there's a line break
sw.WriteLine("{0:yyyy-MM-dd HH:mm:ss} - Start", DateTime.Now);
// no extra parameters
sw.WriteLine("The current time is {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);

假设您想逐行处理文件,您可能会使用 StreamReader 而不是将整个文件加载到 StringBuilder 并通过换行符将其拆分为数组,对吗?使用 StringReader,您可以通过从 TextBox 或 Web 表单中的字符串创建 StringReader 来使用完全相同的方法(只要它采用通用 TextReader)。

Linq2Sql DataContexts 有一个 Log 属性,您可以将其设置为 TextWriter,以便在执行查询之前输出查询以查看正在运行的确切内容。您可以将其设置为附加到文件的 TextWriter,但您可以将 StringWriter 附加到它并在测试时在网页底部输出内容...

于 2010-11-30T04:47:36.990 回答
1

您可以使用 StringReader 从字符串中读取所有整数。

private static void Main()
{
    var str = @"
                13
                13
                0 6
                0 5
                0 1
                0 2
                5 3
                6 4
                5 4
                3 4
                7 8
                9 10
                11 12
                9 11
                9 12";


    using (StandardInput input = new StandardInput(new StringReader(str)))
    {
        List<int> integers = new List<int>();
        int n;
        while ((n = input.ReadInt32()) != -1)
        {
            integers.Add(n);
        }
    }
}

标准输入类:

class StandardInput : IDisposable
{
    private readonly TextReader reader;

    public StandardInput(TextReader reader)
    {
        this.reader = reader;
    }

    public int ReadInt32()
    {
        while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != -1)
        {
            reader.Read();
        }
        var builder = new StringBuilder();
        while (char.IsDigit((char) reader.Peek()))
            builder.Append((char) reader.Read());

        return builder.Length == 0 ? -1 : int.Parse(builder.ToString());
    }

    public double ReadDouble()
    {
        while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != '.'
                                                  && reader.Peek() != -1)
        {
            reader.Read();
        }
        var builder = new StringBuilder();
        if (reader.Peek() == '.')
            builder.Append((char) reader.Read());
        while (char.IsDigit((char)reader.Peek()))
            builder.Append((char)reader.Read());
        if (reader.Peek() == '.' && !builder.ToString().Contains("."))
        {
            builder.Append((char)reader.Read());
            while (char.IsDigit((char)reader.Peek()))
                builder.Append((char)reader.Read());
        }
        return builder.Length == 0 ? -1 : double.Parse(builder.ToString());
    }

    public void Dispose()
    {
        reader.Dispose();
    }
}
于 2014-09-08T13:35:56.727 回答
0

我不确定谁告诉你他们的目的是与 StringBuilder 一起使用,但这绝对不正确。正如您所指出的,可以在不使用其他类的情况下读取和写入 StringBuilder。StringWriter 和 StringReader 类扩展了 TextReader 和 TextWriter .Net Framework 基类,并为处理文本数据提供了类似流的功能。例如,如果您需要使用某些 XmlDocument 类型的类,则某些方法允许您通过 TextReader 加载 Xml 数据,因此如果您将 Xml 文本作为字符串变量,您可以将其加载到 StringReader然后将其提供给 XmlDocument。

于 2010-08-03T00:35:38.767 回答