StringReaderクラスとStringWriterクラスは、文字列を一種のストリームとみなして読み込み・書き込みを行うクラスです。 これらのクラスの一番のポイントは、TextReader/TextWriterの派生クラスである点です。 StreamReaderクラスとStreamWriterクラスもTextReader/TextWriterから派生したクラスですが、これらのクラスと共通したメソッドを持つため、文字列のストリームであろうとファイルのストリームであろうと区別することなく同じ処理を行うことが出来ます。
また、StringReader/StringWriterを使うことによって、一時ファイルを使わずにメモリ上のでテキストの読み込み/書き込みを行うといったことも可能になります。
以下ではStringReader/StringWriterに固有な部分のみを解説します。 個々のメソッドの使い方など、基本的な操作についてはStreamReaderクラス・StreamWriterクラスを参照してください。
StringReaderクラス
StringReaderクラスはStringクラスの文字列をストリームとみなして読み込みを行うクラスです。 コンストラクタに読み込みたい文字列を含むStringを指定することで、その文字列から読み込みを行うStringReaderのインスタンスを生成できます。
以下は、StringReaderとStreamReaderを使って、文字列およびファイルをXMLとして読み込み、要素"/foo/bar"のテキストを表示する例です。 XMLの読み込みは共通のメソッドである点に注目してください。
using System;
using System.IO;
using System.Xml;
class Sample {
static void Main()
{
string xmlText = "<?xml version=\"1.0\"?><foo><bar>hoge</bar></foo>";
// Stringから読み込む
using (StringReader r = new StringReader(xmlText)) {
ReadXml(r);
}
// ファイルから読み込む
using (StreamReader r = new StreamReader("sample.xml")) {
ReadXml(r);
}
}
static void ReadXml(TextReader reader)
{
XmlDocument document = new XmlDocument();
document.Load(reader);
Console.WriteLine(document.InnerXml);
Console.WriteLine(document.SelectSingleNode("/foo/bar/text()").Value);
}
}
Imports System
Imports System.IO
Imports System.Xml
Class Sample
Shared Sub Main()
Dim xmlText As String = "<?xml version=""1.0""?><foo><bar>hoge</bar></foo>"
' Stringから読み込む
Using r As New StringReader(xmlText)
ReadXml(r)
End Using
' ファイルから読み込む
Using r As New StreamReader("sample.xml")
ReadXml(r)
End Using
End Sub
Shared Sub ReadXml(ByVal reader As TextReader)
Dim document As New XmlDocument()
document.Load(reader)
Console.WriteLine(document.InnerXml)
Console.WriteLine(document.SelectSingleNode("/foo/bar/text()").Value)
End Sub
End Class
<?xml version="1.0"?>
<foo>
<baz>hoge</baz>
<bar>piyo</bar>
</foo>
<?xml version="1.0"?><foo><bar>hoge</bar></foo> hoge <?xml version="1.0"?><foo><baz>hoge</baz><bar>piyo</bar></foo> piyo
StringReaderを使うことにより、StreamReaderのメソッドを使ってファイルから読み込むのと同様に文字列を扱うことができます。 次の例では、既存の文字列を読み込み、一行毎に分割して表示しています。
using System;
using System.IO;
using System.Xml;
class Sample {
static void Main()
{
// 複数の"行"が含まれる文字列
string text = "foo\r\nbar\r\nhoge\r\npiyo";
using (StringReader r = new StringReader(text)) {
for (;;) {
// StringReaderを使って文字列textから"一行"ずつ読み込む
string line = r.ReadLine();
if (line == null) break;
Console.WriteLine(line);
}
}
}
}
foo bar hoge piyo
StringWriterクラス
StringWriterクラスはStringBuilderクラスを出力先のストリームとみなして書き込みを行うクラスです。 Stringクラスは不変であるため、代わりにStringBuilderが書き込み先に使用されます。 コンストラクタに書き込み先となるStringBuilderを指定することで、そのStringBuilderへ書き込みを行うStringWriterのインスタンスを生成できます。
以下は、StringWriterとStreamWriterを使って、作成したXMLドキュメントをファイルと文字列に書き出す例です。 XMLドキュメントの作成と書き込みは共通のメソッドである点に注目してください。
using System;
using System.IO;
using System.Text;
using System.Xml;
class Sample {
static void Main()
{
StringBuilder sb = new StringBuilder();
// StringBuilderに書き込む
using (StringWriter w = new StringWriter(sb)) {
WriteXml(w);
}
Console.WriteLine(sb);
// ファイルに書き込む
using (StreamWriter w = new StreamWriter("sample.xml")) {
WriteXml(w);
}
}
static void WriteXml(TextWriter writer)
{
XmlDocument document = new XmlDocument();
document.LoadXml("<?xml version=\"1.0\"?><foo><bar>hoge</bar></foo>");
document.Save(writer);
}
}
Imports System
Imports System.IO
Imports System.Text
Imports System.Xml
Class Sample
Shared Sub Main()
Dim sb As New StringBuilder()
' StringBuilderに書き込む
Using w As New StringWriter(sb)
WriteXml(w)
End Using
Console.WriteLine(sb)
' ファイルに書き込む
Using w As New StreamWriter("sample.xml")
WriteXml(w)
End Using
End Sub
Shared Sub WriteXml(ByVal writer As TextWriter)
Dim document As New XmlDocument()
document.LoadXml("<?xml version=""1.0""?><foo><bar>hoge</bar></foo>")
document.Save(writer)
End Sub
End Class
<?xml version="1.0"?> <foo> <bar>hoge</bar> </foo>
<?xml version="1.0"?> <foo> <bar>hoge</bar> </foo>
StringWriterでは、コンストラクタにStringBuilderを指定しなくてもインスタンスを生成することが出来ます。 この場合、暗黙的にStringBuilderが生成されStringWriterで使用されます。 書き込んだ内容は、GetStringBuilderメソッドやToStringメソッドを使って取得できます。
using System;
using System.IO;
using System.Text;
class Sample {
static void Main()
{
using (StringWriter w = new StringWriter()) {
w.Write("The quick brown fox");
w.WriteLine(" jumps over the lazy dog");
Console.WriteLine("Length: {0}", w.GetStringBuilder().Length);
Console.WriteLine("Capacity:{0}", w.GetStringBuilder().Capacity);
Console.WriteLine(w.ToString());
}
}
}
Imports System
Imports System.IO
Imports System.Text
Class Sample
Shared Sub Main()
Using w As New StringWriter()
w.Write("The quick brown fox")
w.WriteLine(" jumps over the lazy dog")
Console.WriteLine("Length: {0}", w.GetStringBuilder().Length)
Console.WriteLine("Capacity:{0}", w.GetStringBuilder().Capacity)
Console.WriteLine(w.ToString())
End Using
End Sub
End Class
Length: 44 Capacity:86 The quick brown fox jumps over the lazy dog