web-dev-qa-db-ja.com

StringBuilder対StringWriter / StringReader

私は最近StringWriterStringReaderStringBuilderからの書き込みと読み取りに使用されることを読みました。

まあ私がStringBuilderオブジェクトを使うとき、それは自己完結型のクラスのように見えます。

StringBuilder.Append()Insert()Replace()Remove()などを使用して、StringBuilderを読み書きするあらゆる方法があります。 ..

  1. StringWriter自体では実行できないStringReaderおよびStringBuilderの可能な使用法は何ですか?
  2. それらの実際の用途は何ですか?
  3. 入力としてStreamを使用していない可能性のある理由は何ですか(他のライターとリーダーが操作対象のコンストラクタパラメータとしてストリームを使用しているため)が、StringBuilderですか?
33

StringBuilder自体では実行できないStringWriterとStringReaderの可能な使用法は何ですか?

StringReaderおよびStringWriterは、それぞれTextReaderおよびTextWriterから派生します。つまり、彼らができることはTextReaderまたはTextWriterインスタンスとして機能しますが、stringまたはStringBuilderはこれらのタイプのいずれも派生しないため、インスタンスとして機能しません。

それらの実際の用途は何ですか?

これらを使用すると、TextReaderまたはTextWriterがある場合に、stringまたはStringBuilderが必要なAPIを呼び出すことができます。

入力としてStreamを使用していない可能性がある理由は何ですか(他のライターおよびリーダーが操作対象のコンストラクターパラメーターとしてStreamを使用しているため)が、StringBuilderですか?

ストリームでは機能しないためです。 stringsまたはStringBuildersで動作します。これらは、異なるインターフェースを必要とするAPIにこれらの型を適応させる単純なラッパークラスです。参照: アダプタパターン

33
Greg Beech

他の人はすでに言っていますが、それはそれらがTextReader/TextWriterから派生し、それらの代わりに使用できるためです。 1つには、コンテンツを文字列としてのみ必要な場合は、ファイルに使用するのと同じ方法で行を出力するほうが理にかなっています。メモリ内の複数の行にまたがる出力が必要な場合は、わざわざ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);

ファイルを1行ずつ処理したいとします。おそらく、ファイル全体をStringBuilderにロードして改行文字で配列に分割するのではなく、StreamReaderを使用するでしょう。 StringReaderを使用すると、TextBoxまたはWebフォームの文字列からStringReaderを作成することにより、(汎用のTextReaderが必要である限り)まったく同じメソッドを使用できます。

Linq2Sql DataContextsには、実行されているものを正確に確認するために実行する前にクエリを出力するためにTextWriterに設定できるLogプロパティがあります。これをファイルに添付されたTextWriterに設定できますが、それにStringWriterを添付して、テスト時にWebページの下部にコンテンツを出力できます...

5
Jason Goemaat

彼らの目的がStringBuilderで使用することであったと誰が言ったのかはわかりませんが、それは完全に間違っています。お気づきのとおり、StringBuilderは、別のクラスを使用せずに読み書きできます。 StringWriterおよびStringReaderクラスは、TextReaderおよびTextWriter .Net Framework基本クラスを拡張し、テキストデータを操作するためのストリームのような機能を提供します。たとえば、一部のXmlDocumentタイプのクラスを操作する必要がある場合、一部のメソッドでは、TextReaderを介してXmlデータを読み込むことができます。したがって、Xmlテキストを文字列変数として持っている場合、それをStringReaderに読み込むことができます。そして、それをXmlDocumentに提供します。

1
EchoCoder

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

StandardInputクラス:

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();
    }
}
1
Raz Megrelidze