【Stream—3】StreamWriter 相关知识分享
在介绍StreamWriter之前,我们首先来了解一下它的父类TextWriter。
一、TextWriter
1、TextWriter的构造函数和常用属性方法
下面是TextWriter的构造函数:
和所有抽象类一样,该类不能直接实例化,它有两个构造函数。
特别说一下第二个构造函数,大家发现这个构造函数中有一个类型IFomatProvider类型的参数,这个是什么东东呢?
IFomatProvider接口的简单介绍
其实,IFomatProvider接口从字面上就能理解了,一个格式化的提供者。大家记得我们常用的string.Format("{0:P}",data);么?IFomatProvider在这里被隐式调用了。
关于隐式调用的各种方式,用个简单的例子向大家说明一下:
1 //有关数字格式化隐性使用IFomatProvider的例子 2 #if true 3 //货币 4 Console.WriteLine(string.Format("显示货币格式{0:c3}",12)); 5 //十进制 6 Console.WriteLine("显示货币十进制格式{0:d10}", 12); 7 //科学计数法 8 Console.WriteLine("科学计数法{0:e5}",12); 9 //固定点格式 10 Console.WriteLine("固定点格式 {0:f10}",12); 11 //常规格式 12 Console.WriteLine("常规格式{0:g10}",12); 13 //数字格式(用分号隔开) 14 Console.WriteLine("数字格式 {0:n5}:",666666666); 15 //百分号格式 16 Console.WriteLine("百分号格式(不保留小数){0:p0}",0.55); 17 //16进制 18 Console.WriteLine("16进制{0:x0}", 12); 19 // 0定位器 此示例保留5位小数,如果小数部分小于5位,用0填充 20 Console.WriteLine("0定位器{0:000.00000}",1222.133); 21 //数字定位器 22 Console.WriteLine("数字定位器{0:(#).###}", 0200.0233000); 23 //小数 24 Console.WriteLine("小数保留一位{0:0.0}", 12.222); 25 //百分号的另一种写法,注意小数的四舍五入 26 Console.WriteLine("百分号的另一种写法,注意小数的四舍五入{0:0%.00}", 0.12345); 27 Console.WriteLine("\n\n"); 28 #endif
输出结果:
也就是说IFomatProvider提供了一个格式化的工具,让我们通过NumberFomatInfo类来了解一下
这个密封类实现了IFomatProvider接口,主要实现了一个数字格式化的类,下面是一些规定的格式化说明符:
让我们用简单易懂的代码来实现NumberFomatInfo如何使用:
1 #if true 2 //显性使用IFomatProvider 3 Console.WriteLine("显性使用IFomatProvider的例子"); 4 //实例化numberFomatProvider对象 5 NumberFormatInfo numberFomatProvider = new NumberFormatInfo(); 6 //设置该provider对于货币小数的显示长度 7 numberFomatProvider.CurrencyDecimalDigits = 10; 8 //注意:我们可以使用C+数字形式来改变provider提供的格式 9 Console.WriteLine(string.Format(numberFomatProvider, "provider设置的货币格式{0:C}", 12)); 10 Console.WriteLine(string.Format(numberFomatProvider, "provider设置的货币格式被更改了:{0:C2}", 12)); 11 Console.WriteLine(string.Format(numberFomatProvider, "默认百分号和小数形式{0:p2}", 0.12)); 12 //将小数 “.”换成"?" 13 numberFomatProvider.PercentDecimalSeparator = "?"; 14 Console.WriteLine(string.Format(numberFomatProvider, "provider设置的百分号和小数形式{0:p2}", 0.12)); 15 Console.ReadLine(); 16 #endif
输出结果:
正如上述代码表示的,IFormatProvider提供用于检索控制格式化的对象的机制,我们甚至可以自定义Provider类来实现特殊的字符串格式化,关于这个重要的知识点,我会在另外一篇博文中详细介绍并自定义一个简单的FomatInfo类。
言归正传,让我们了解一下TextWriter的几个重要属性
TextWriter重要属性:
(1)、Encoding:可以获得当前TextWriter的Encoding
(2)、FomatProvider:可以获得当前TextWriter的FomatProvider
(3)、NewLine:每当调用WriteLine()方法是,行结束字符串都会写入到文本流中,该属性就是读取该结束字符串。
TextWriter重要方法:
(1)、Close():关闭TextWriter并且释放TextWriter的资源
(2)、Dispose():释放TextWriter所占用的所有资源(和StreamReader相似,一旦TextWriter被释放,它所占用的资源如Stream会一并释放)
(3)、Flush():和Stream类中一样,将缓冲区所有的数据立刻写入文件(基础设备)
(4)、Write():方法的重载(这个方法重载太多,所以这里不全写出了,大家可以参考最后一个例子,打印结果)
(5)、WriteLine():方法的重载,和Write()方法相比,区别在于每个重载执行完毕之后都会附加写入一个换行符
二、StreamWriter
首先我们先了解一下StreamWriter的概念:实现一个TextWriter,使其以一种特定的编码向流中写入字符。
那会有很多朋友疑惑,StreamWriter和TextWriter有什么区别呢?
其实从名字定义我们便可区别了,TextWriter分别是对连续字符系列处理的编写器,而StreamWriter通过特定的编码和流的方式对数据进行处理的编写器。
1、StreamWriter的构造函数:
(1)、public StreamWriter(string path); 参数path表示文件所在的位置
(2)、public StreamWriter(Stream stream,Encoding encoding);参数Stream表示可以接收Stream的任何子类或派生类,Encoding表示让StreamWriter在写操作时使用该Encoding进行性编码操作
(3)、public StreamWriter(string path,bool append);第二个append参数非常重要,当append参数为true时,StreamWriter会通过path去找当前文件是否存在,如果存在则进行append或overwrite的操作,否则创建新的文件
(4)、public StreamWriter(Stream stream,Encoding encoding,int bufferSize);bufferSize参数设置当前StreamWriter的缓冲区的大小
2、SteamWriter的属性
StreamWriter的方法大多都继承了TextWriter这里就不再重复叙述了,这里就简单介绍一下StreamWriter独有的属性:
(1)、AutoFlush:这个值来指示每次使用Write()方法后直接将缓冲区的数据写入文件(基础流)
(2)、BaseStream:和StreamReader相似,可以取出当前的Stream对象加以处理
三、StreamWriter示例:
下面我们就简单的几个示例来看一下以上的属性方法如何使用的:
1 const string txtFilePath = "D:\\TextWriter.txt"; 2 3 static void Main(string[] args) 4 { 5 6 NumberFormatInfo numberFomatProvider = new NumberFormatInfo(); 7 //将小数 “.”换成"?" 8 numberFomatProvider.PercentDecimalSeparator = "?"; 9 StreamWriterTest test = new StreamWriterTest(Encoding.Default, txtFilePath, numberFomatProvider); 10 //StreamWriter 11 test.WriteSomthingToFile(); 12 //TextWriter 13 test.WriteSomthingToFileByUsingTextWriter(); 14 Console.ReadLine(); 15 } 16 } 17 18 /// <summary> 19 /// TextWriter和StreamWriter的举例 20 /// </summary> 21 public class StreamWriterTest 22 { 23 /// <summary> 24 /// 编码 25 /// </summary> 26 private Encoding _encoding; 27 28 /// <summary> 29 /// IFomatProvider 30 /// </summary> 31 private IFormatProvider _provider; 32 33 /// <summary> 34 /// 文件路径 35 /// </summary> 36 private string _textFilePath; 37 38 39 public StreamWriterTest(Encoding encoding, string textFilePath) 40 : this(encoding, textFilePath, null) 41 { 42 43 } 44 45 public StreamWriterTest(Encoding encoding, string textFilePath, IFormatProvider provider) 46 { 47 this._encoding = encoding; 48 this._textFilePath = textFilePath; 49 this._provider = provider; 50 } 51 52 /// <summary> 53 /// 我们可以通过FileStream 或者 文件路径直接对该文件进行写操作 54 /// </summary> 55 public void WriteSomthingToFile() 56 { 57 //获取FileStream 58 using (FileStream stream = File.OpenWrite(_textFilePath)) 59 { 60 //获取StreamWriter 61 using (StreamWriter writer = new StreamWriter(stream, this._encoding)) 62 { 63 this.WriteSomthingToFile(writer); 64 } 65 66 //也可以通过文件路径和设置bool append,编码和缓冲区来构建一个StreamWriter对象 67 using (StreamWriter writer = new StreamWriter(_textFilePath, true, this._encoding, 20)) 68 { 69 this.WriteSomthingToFile(writer); 70 } 71 } 72 } 73 74 /// <summary> 75 /// 具体写入文件的逻辑 76 /// </summary> 77 /// <param name="writer">StreamWriter对象</param> 78 public void WriteSomthingToFile(StreamWriter writer) 79 { 80 //需要写入的数据 81 string[] writeMethodOverloadType = 82 { 83 "1.Write(bool);", 84 "2.Write(char);", 85 "3.Write(Char[])", 86 "4.Write(Decimal)", 87 "5.Write(Double)", 88 "6.Write(Int32)", 89 "7.Write(Int64)", 90 "8.Write(Object)", 91 "9.Write(Char[])", 92 "10.Write(Single)", 93 "11.Write(Char[])", 94 "12.Write(String)", 95 "13Write(UInt32)", 96 "14.Write(string format,obj)", 97 "15.Write(Char[])" 98 }; 99 100 //定义writer的AutoFlush属性,如果定义了该属性,就不必使用writer.Flush方法 101 writer.AutoFlush = true; 102 writer.WriteLine("这个StreamWriter使用了{0}编码", writer.Encoding.HeaderName); 103 //这里重新定位流的位置会导致一系列的问题 104 //writer.BaseStream.Seek(1, SeekOrigin.Current); 105 writer.WriteLine("这里简单演示下StreamWriter.Writer方法的各种重载版本"); 106 107 writeMethodOverloadType.ToList().ForEach 108 ( 109 (name) => { writer.WriteLine(name); } 110 ); 111 writer.WriteLine("StreamWriter.WriteLine()方法就是在加上行结束符,其余和上述方法是用一致"); 112 //writer.Flush(); 113 writer.Close(); 114 } 115 116 public void WriteSomthingToFileByUsingTextWriter() 117 { 118 using (TextWriter writer = new StringWriter(_provider)) 119 { 120 writer.WriteLine("这里简单介绍下TextWriter 怎么使用用户设置的IFomatProvider,假设用户设置了NumberFormatInfoz.PercentDecimalSeparator属性"); 121 writer.WriteLine("看下区别吧 {0:p10}", 0.12); 122 Console.WriteLine(writer.ToString()); 123 writer.Flush(); 124 writer.Close(); 125 } 126 127 } 128 }
输出结果:
TextWriter输出结果:
好了,这次的StreamWriter就介绍到这里了。非常感谢 逆时针の风 的博客对我的帮助。