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就介紹到這裡了。非常感謝 逆時針の風 的部落格對我的幫