私は最近StringWriter
とStringReader
がStringBuilder
からの書き込みと読み取りに使用されることを読みました。
まあ私がStringBuilder
オブジェクトを使うとき、それは自己完結型のクラスのように見えます。
StringBuilder.Append()
、Insert()
、Replace()
、Remove()
などを使用して、StringBuilder
を読み書きするあらゆる方法があります。 ..
StringWriter
自体では実行できないStringReader
およびStringBuilder
の可能な使用法は何ですか?Stream
を使用していない可能性のある理由は何ですか(他のライターとリーダーが操作対象のコンストラクタパラメータとしてストリームを使用しているため)が、StringBuilder
ですか?StringBuilder自体では実行できないStringWriterとStringReaderの可能な使用法は何ですか?
StringReader
およびStringWriter
は、それぞれTextReader
およびTextWriter
から派生します。つまり、彼らができることはTextReader
またはTextWriter
インスタンスとして機能しますが、string
またはStringBuilder
はこれらのタイプのいずれも派生しないため、インスタンスとして機能しません。
それらの実際の用途は何ですか?
これらを使用すると、TextReader
またはTextWriter
がある場合に、string
またはStringBuilder
が必要なAPIを呼び出すことができます。
入力としてStreamを使用していない可能性がある理由は何ですか(他のライターおよびリーダーが操作対象のコンストラクターパラメーターとしてStreamを使用しているため)が、StringBuilderですか?
ストリームでは機能しないためです。 string
sまたはStringBuilder
sで動作します。これらは、異なるインターフェースを必要とするAPIにこれらの型を適応させる単純なラッパークラスです。参照: アダプタパターン 。
他の人はすでに言っていますが、それはそれらが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ページの下部にコンテンツを出力できます...
彼らの目的がStringBuilderで使用することであったと誰が言ったのかはわかりませんが、それは完全に間違っています。お気づきのとおり、StringBuilderは、別のクラスを使用せずに読み書きできます。 StringWriterおよびStringReaderクラスは、TextReaderおよびTextWriter .Net Framework基本クラスを拡張し、テキストデータを操作するためのストリームのような機能を提供します。たとえば、一部のXmlDocumentタイプのクラスを操作する必要がある場合、一部のメソッドでは、TextReaderを介してXmlデータを読み込むことができます。したがって、Xmlテキストを文字列変数として持っている場合、それをStringReaderに読み込むことができます。そして、それをXmlDocumentに提供します。
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();
}
}