之前的文章介绍了StreamReader类,本文主要介绍StreamWriter类,我们先看一下StreamWriter的定义:
public class StreamWriter : System.IO.TextWriter
TextWriter类是一个抽象类,StreamWriter是它的一个子类。.Net Framework设计抽象类TextWriter,它的目的是什么?
它主要是作为一个writer对象,负责对目标写入字符串,这个目标可能是一段文本字符,也可能是二进制流。
下面我主要列出来它的主要成员:
public abstract class TextWriter : MarshalByRefObject, IDisposable
{
Encoding Encoding;
IFormatProvider FormatProvider;
string NewLine;
void Close();
void Dispose();
void Flush();
TextWriter Synchronized(TextWriter writer);
void Write(char value);
void Write(char[] buffer);
void Write(char[] buffer, int index, int count);
void Write(string value);
void Write(bool value);
void Write(int value);
void Write(long value);
void Write(float value);
void Write(object value);
void Write(string format, params object[] arg);
void WriteLine(char value);
...
}
属性有三个。
Encoding:通过TextWriter写入的数据,如果需要转化成二进制流的话,使用什么编码格式。
FormatProvider:通过TextWriter写入的数据对象,我们可以通过提供FormatProvider,就可以控制数据对象的输出格式。后面的原理和string.Format原理一模一样,可以查看我之前的文章。
NewLine:表示当前的行终止符字符串,默认是回车符后跟换行符 \r\n 。这里的值只允许两种可能 \r\n 和 \n 。如果设置为null, 则使用默认的换行符。WriteLine方法和Write方法的区别就是在写入的数据对象后面追加了NewLine属性值。
主要的方法有Write,WriteLine,Synchronized,Flush,Dispose和Close方法。
Write方法:它将传入的参数,写入文本字符串或者二进制流中。它根据传入的参数的类型,提供了各种各样的重载。下面这几种函数的重载类似,就是把数据对象写入目标中:
void Write(char value);
void Write(char[] buffer);
void Write(char[] buffer, int index, int count);
void Write(string value);
void Write(bool value);
void Write(int value);
void Write(long value);
void Write(float value);
void Write(object value);
如果想要自定义传入的数据对象的写入格式,使用这个重载:
void Write(string format, params object[] arg);
这个方法在.Net Framework的定义如下:
public virtual void Write(string format, params object[] arg)
{
this.Write(string.Format(this.FormatProvider, format, arg));
}
在方法的内部会使用FormatProvider属性的值。并使用了string.Format方法来控制对象的格式。具体是细节请参考之前的文章,这里不作具体讨论。
WriteLine方法:和Write方法类似,唯一的区别就是在写入传入的数据之后追加了NewLine属性值。
void WriteLine(char value)
{
this.Write(value);
this.WriteLine();
}
Synchronized方法:创建一个线程安全的TextWriter。通过传入一个TextWriter对象,然后对TextWriter对象进行线程安全方面的包装并返回,返回的对象所有写操作都是线程安全的。
Flush方法:清除当前编写器的所有缓冲区,并将所有缓冲的数据写入底层设备。
Close/Dispose方法:关闭当前编写器并释放与编写器关联的所有系统资源。
学习TextWriter类之后,我们会使用StringWriter来对TextWriter类做一个简单的练习,在之前简单认识一下StringWriter:
public class StringWriter : TextWriter
{
public StringWriter();
public StringWriter(IFormatProvider formatProvider);
public StringWriter(StringBuilder sb);
public StringWriter(StringBuilder sb, IFormatProvider formatProvider);
public virtual StringBuilder GetStringBuilder();
public override string ToString();
public override void Write(string value);
...
}
在StringWriter类中,有两个比较重要的成员:
StringBuilder sb;
IFormatProvider formatProvider;
sb就是StringWriter对象的写入的目标,在调用任何Write方法之后,传入的数据对象会保存在sb里面,这个对象可以通过GetStringBuilder()得到,调用StringWriter对象的ToString()方法,返回的就是sb里面的字符串。
public override string ToString()
{
return this._sb.ToString();
}
我们使用StringWriter来对TextWriter类做一个简单的练习:
using (TextWriter writer = new StringWriter())
{
writer.Write("I'm Nestor.");
writer.WriteLine("I am 31 years old.");
writer.WriteLine("I have been working in 8 years.");
Console.Write(writer.ToString());
}
我们现在对TextWriter已经有了很好的认识,我们现在再重新认识一下StreamWriter类。
在.Net Framework中设计StreamWriter类的目的是什么?
实现TextWriter抽象类,并可以把文本字符串写入特定编码格式的二进制流中。
public class StreamWriter : TextWriter
{
bool AutoFlush;
Stream BaseStream;
Encoding Encoding;
public StreamWriter(Stream stream);
public StreamWriter(Stream stream, Encoding encoding);
public StreamWriter(Stream stream, Encoding encoding, int bufferSize);
public StreamWriter(string path);
public StreamWriter(string path, bool append);
public StreamWriter(string path, bool append, Encoding encoding);
public StreamWriter(string path, bool append, Encoding encoding, int bufferSize);
public override void Flush();
public override void Close();
public override void Write(string value);
...
}
在构造一个StreamWriter对象的时候:
1.我们需要传入一个流或者一个文件路径。
2.可以提供一个Encoding,默认是UTF8。
3.可以设置缓存区大小,默认是1024。
4.传入文件路径的话,是否在文件流尾部写入数据,还是重写整个文件。
属性有三。
AutoFlush:在完成Write方法之后,是否自动Flush数据。
BaseStream:获取StreamWriter内部的数据流。
Encoding:获取StreamWriter内部的编码信息。
方法
Flush方法:清除当前编写器的所有缓冲区,并将所有缓冲的数据写入底层设备。
Close/Dispose方法:关闭当前编写器并释放与编写器关联的所有系统资源。
我们对StreamWriter进行一个小练习:
string txtFilePath = @"C:\Temp\MyTest.txt";
using (FileStream stream = File.Open(txtFilePath, FileMode.Append))
{
using (TextWriter writer = new StreamWriter(stream))
{
writer.Write("I'm Nestor.");
writer.WriteLine("I am 31 years old.");
writer.Write("I have been working in 8 years..");
writer.Flush();
}
}
using (TextWriter writer = new StreamWriter(txtFilePath, true))
{
writer.Write("_I'm Nestor.");
writer.WriteLine("_I am 31 years old.");
writer.Write("_I have been working in 8 years..");
writer.Flush();
}
最后我们总结一下:
TextWriter类是一个抽象类,主要是作为一个writer对象,负责对目标写入文本字符,这个目标可能是一段字符,也可能是二进制流。
StringWriter类是TextWriter的具体实现,它内部维护了一个StringBuilder类型的字段,用于存储一段文本字符。我们写入数据到这个字段中。
StreamWriter类是TextWriter的具体实现,通过它可以把文本字符串写入特定编码格式的二进制流中。
最后我们看看TextWriter,StringWriter和StreamWriter的OO图: