轉自 C# StreamReader/StreamWriter與FileStream用法詳解
一、<1>StreamReader類共有10個構造函數
- StreamReader (Stream) // 為指定的流初始化 StreamReader 類的新實例。
- FileStream fs = new FileStream(@"D:\Readme.txt",FileMode.Open);
- StreamReader sr = new StreamReader(fs);
- StreamReader (String) // 為指定的文件名初始化 StreamReader 類的新實例。
- StreamReader sr = new StreamReader(@"D:\Readme.txt");
- StreamReader (Stream, Boolean) // 用指定的字節順序(BOM)標記檢測選項,為指定的流初始化 StreamReader 類的一個新實例。
- StreamReader sr = new StreamReader( (System.IO.Stream)File.OpenRead(@"D:\Readme.txt"),true);
- StreamReader (Stream, Encoding) // 用指定的字符編碼為指定的流初始化 StreamReader 類的一個新實例。(StreamReader默認的編碼是Unicode,UTF-8是其子集)
- FileStream fs = new FileStream(@"D:\Readme.txt" , FileMode.Open );
- nbsp;StreamReader sr = new StreamReader(fs,Encoding.GetEncoding("GB2312"));
- StreamReader (String, Boolean) // 為指定的文件名初始化 StreamReader 類的新實例,帶有指定的字節順序標記檢測選項。
- StreamReader (String, Encoding) // 用指定的字符編碼,為指定的文件名初始化 StreamReader 類的一個新實例。
- StreamReader (Stream, Encoding, Boolean) // 為指定的流初始化 StreamReader 類的新實例,帶有指定的字符編碼和字節順序標記檢測選項。
- StreamReader (String, Encoding, Boolean) // 為指定的文件名初始化 StreamReader 類的新實例,帶有指定的字符編碼和字節順序標記檢測選項。
- StreamReader (Stream, Encoding, Boolean, Int32) // 為指定的流初始化 StreamReader 類的新實例,帶有指定的字符編碼、字節順序標記檢測選項和緩沖區大小。
- FileStream fs = new FileStream(@"D:\Readme.txt" , FileMode.Open);
- StreamReader sr = new StreamReader(fs,Encoding.ASCII,true,512);
- StreamReader (String, Encoding, Boolean, Int32) //為指定的文件名初始化 StreamReader 類的新實例,帶有指定字符編碼、字節順序標記檢測選項和緩沖區大小。
- StreamReader sr = new StreamReader(@"D:\Readme.txt",Encoding.ASCII,true,512);
一、<2>StreamReader常用方法
- Read () // 單字符讀入(文件指針不移動)
- public override int Read (); //讀取輸入流中的下一個字符並使該字符的位置提升一個字符,返回的是字符的十進制值。
- StreamReader sr = new StreamReader(@"D:\Readme.txt",Encoding.GetEncoding("GB2312")); //通常需要轉碼為GB2312
- int Ichar = 0;
- while ((Ichar = sr.Read()) != -1) // 不再有可用的字符,則為 -1
- {
- MessageBox.Show(Convert.ToChar(Ichar).ToString()); //將int類型轉成ASCII字符
- }
- public override int Read (char[] buffer,int index,int count); //從當前流中將最多的 count 個字符讀入到buffer數組中,從buffer數組從index位開始寫入,返回值為讀取的字符總數。
- char[] buffer = new char[512];
- int readCount = sr.Read(buffer, 0, 512);
- for (int i = 0; i < readCount; i++)
- {
- MessageBox.Show(buffer[i].ToString());
- }
- ReadLine() // 行讀入
- 方法原型:public override string ReadLine () // 輸入流中的下一行;如果到達了輸入流的末尾,則為空引用
- string strLine = null;
- while ((strLine = sr.ReadLine()) != null)
- {
- MessageBox.Show(strLine);
- }
- ReadToEnd() // 從流的當前位置到末尾讀取流。
- 方法原型:public override string ReadToEnd (); // 如果當前位置位於流的末尾,則返回空字符串 ("")。
備注:用該方法可以把數據流一次性全部加載到內存中,內存中數據的操作的速度是非常快的,但要注意的是,如果文件太大的話,可能內存會不夠,就用Read或ReadLine()方法讀取。
- string strLine = sr.ReadToEnd();
- MessageBox.Show(strLine);
- Peek () //讀取下 一個字符,但位置不移動
- 方法原型:public override int Peek ()
- while (sr.Peek() != -1)
- {
- MessageBox.Show(sr.ReadLine());
- }
一、<3>StreamReader常用屬性:
- EndOfStream // 獲取一個值,該值表示當前的流位置是否在流的末尾。
- while (!sr.EndOfStream)
- {
- MessageBox.Show(sr.ReadLine());
- }
- CurrentEncoding // 獲取當前 StreamReader 對象正在使用的當前字符編碼
- MessageBox.Show(sr.CurrentEncoding.EncodingName);
- BaseStream // 返回基礎流。
二、<1>StreamWriter類共有7個構造函數:
- StreamWriter (Stream) // 用 UTF-8 編碼及默認緩沖區大小,為指定的流初始化 StreamWriter 類的一個新實例。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.CreateNew);
- StreamWriter sw = new StreamWriter(fs);
- StreamWriter (String) // 使用默認編碼和緩沖區大小,為指定路徑上的指定文件初始化StreamWriter 類的新實例。
- StreamWriter sw = new StreamWriter(@"D:\a.txt");
- StreamWriter (Stream, Encoding) // 用指定的編碼及默認緩沖區大小,為指定的流初始化 StreamWriter 類的新實例。(默認寫入編碼為UTF8)
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.CreateNew);
- StreamWriter sw = new StreamWriter(fs,Encoding.UTF8);
- StreamWriter (String, Boolean) // 使用默認編碼和緩沖區大小,為指定路徑上的指定文件初始化 StreamWriter 類的新實例。true表示如果該文件存在,則可以向其追加。false表示將其全部重寫。如果該文件不存在,則此構造函數將創建一個新文件。
- StreamWriter sw = new StreamWriter(@"D:\a.txt", true);
- StreamWriter (Stream, Encoding, Int32) // 用指定的編碼及緩沖區大小,為指定的流初始化 StreamWriter 類的新實例。int為緩沖區大小
- StreamWriter sw = new StreamWriter(fs, Encoding.UTF8,512);
- StreamWriter (String, Boolean, Encoding) // 使用指定編碼和默認緩沖區大小,為指定路徑上的指定文件初始化 StreamWriter 類的新實例。true表示如果該文件存在,則可以向其追加。false表示將其全部重寫。如果該文件不存在,則此構造函數將創建一個新文件。
- StreamWriter sw = new StreamWriter(@"D:\a.txt",true, Encoding.UTF8);
- StreamWriter (String, Boolean, Encoding, Int32) // 使用指定編碼和緩沖區大小,為指定路徑上的指定文件初始化 StreamWriter 類的新實例。true表示如果該文件存在,則可以向其追加。false表示將其全部重寫。如果該文件不存在,則此構造函數將創建一個新文件。
- StreamWriter sw = new StreamWriter(@"D:\a.txt",true, Encoding.UTF8, 512);
二、<2>StreamWriter類常用方法:
- Write() // 寫入流。(該方法有17種重載方法,就不一一解說,講幾個常用的方法)
1、public override void Write(string value) //將字符串寫入流。
- StreamWriter sw = new StreamWriter(@"D:\a.txt",true); //true表示如果a.txt文件已存在,則以追加的方式寫入
- sw.Write(this.textBox1.Text);
- sw.Close();
2、public override void Write(char value) // 按字符寫入
- char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
- for (int i = 0; i < charArray.Length; i++)
- {
- sw.Write(charArray[i]);
- }
3、public override void Write (char[] buffer) // 按字符數組寫入
- char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'g' };
- sw.Write(charArray);
4、public virtual void Write (string format,params Object[] arg) //按指定格式轉換的字符串寫入
- sw.Write("我的期待月薪為{0,9:C4},實現年齡為{1,9},成功率{2,9:P2}", new Object[]{ 20000, 30, 1 });
運行結果:我的期待月薪為¥20,000.0000,實現年齡為 30,成功率 100.00% ,具體請參考stringFormat語法
5 、public override void Write (char[] buffer,int index,int count) // 從buffer數組的第index開始寫入count個字符
- char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' ,'g'};
- sw.Write(charArray , 3, 4);
運行結果:defg
- WriteLine() // 寫入流,后跟行結束符(行結束符樣式可用NewLine屬性設置)。(該方法有18種重載方法,只講常用的)
1、public virtual void WriteLine () //寫入空行,等同於跳到下一行
- sw.WriteLine();
2、public virtual void WriteLine (char value)
3、public virtual void WriteLine (char[] buffer)
4、public virtual void WriteLine (string value)
5、public virtual void WriteLine (string format,params Object[] arg)
6、public virtual void WriteLine (char[] buffer,int index,int count)
7、public virtual void WriteLine (Object value) //
- Flush // 清理當前編寫器的所有緩沖區,並使所有緩沖數據寫入基礎流。
- 方法原型:public override void Flush ()
二、<3>StreamWriter常用屬性:
- AutoFlush // 設置StreamWriter 是否在每次調用 StreamWriter.Write 之后,將其緩沖區刷新到基礎流。
備注:除非我們顯示地調用Flush 或 Close,否則,刷新流不會刷新其基礎編碼器,也就是不會寫入到硬盤中,將 AutoFlush 設置為 true后只要調用write()方法會自動將數據寫入到硬盤中,如果用戶期望您所寫入的設備能夠立即反饋,則將 AutoFlush 設置為 true。
- Encoding // 獲取將輸出寫入到其中的 Encoding。
- MessageBox.Show(sw.Encoding.EncodingName);
- NewLine // 設置由當前 TextWriter 使用的行結束符字符串樣式。
- sw.NewLine = "\t";
- sw.WriteLine("aaa");
- sw.WriteLine("bbb");
運行結果:“aaa bbb ”
- BaseStream //獲取同后備存儲區連接的基礎流。
三、<1>FileStream共有15個構造函數
- FileStream (String, FileMode) // 使用指定的路徑和創建模式初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode)
FileMode成員:- (1)Append 打開現有文件並查找到文件尾,或創建新文件。FileMode.Append 只能同 FileAccess.Write 一起使用。
- (2)Create 創建新文件(如果文件不存在)。如果文件已存在,它將被改寫。這要求 FileIOPermissionAccess.Write。FileMode.Create 等效於這樣的 請求:如果文件不存在,則使用 CreateNew;否則使用 Truncate。
- (3)CreateNew 創建新文件。此操作需要 FileIOPermissionAccess.Write 。如果文件已存在,則將引發 IOException。
- (4)Open 打開現有文件。打開文件的能力取決於 FileAccess 所指定的值。如果該文件不存在,則引發 System.IO.FileNotFoundException。
- (5)OpenOrCreate 打開文件(如果文件存在);否則,創建新文件。如果用 FileAccess.Read 打開文件,則需FileIOPermissionAccess.Read。
- (6)Truncate 打開現有文件。文件一旦打開,就將被截斷為零字節大小。此操作需要 FileIOPermissionAccess.Write。試圖從使用 Truncate 打開的文件中進行讀取將導致異常。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create);
- FileStream (String, FileMode, FileAccess) // 使用指定的路徑、創建模式和讀/寫權限初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileAccess access)
FileAccess成員:
- (1)Read 對文件的讀訪問。可從文件中讀取數據。同 Write 組合即構成讀寫訪問權。
- (2)ReadWrite 對文件的讀訪問和寫訪問。可從文件讀取數據和將數據寫入文件。
- (3)Write 文件的寫訪問。可將數據寫入文件。同 Read 組合即構成讀/寫訪問權。
- (1)Read 對文件的讀訪問。可從文件中讀取數據。同 Write 組合即構成讀寫訪問權。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite);
- FileStream (String, FileMode, FileAccess, FileShare) // 使用指定的路徑、創建模式、讀/寫權限和共享權限創建 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share)
FileShare成員:
- (1)Delete 允許隨后刪除文件(在一個進程進行讀取某文件時,另一個進程可以同時對該文件進行刪除)。
- (2)Inheritable 使文件句柄可由子進程繼承。Win32 不直接支持此功能。
- (3)None 謝絕共享當前文件。文件關閉前,打開該文件的任何請求(由此進程或另一進程發出的請求)都將失敗。
- (4)Read 允許隨后打開文件讀取。如果未指定此標志,則文件關閉前,任何打開該文件以進行讀取的請求(由此進程或另一進程發出的請求)都將失敗。但 是,即使指定了此標志,仍可能需要附加權限才能夠訪問該文件。
- (5)ReadWrite 允許隨后打開文件讀取或寫入。如果未指定此標志,則文件關閉前,任何打開該文件以進行讀取或寫入的請求(由此進程或另一進程發出)都將失敗。但是,即使指定了此標志,仍可能需要附加權限才能夠訪問該文件。
- (6)Write 允許隨后打開文件寫入。如果未指定此標志,則文件關閉前,任何打開該文件以進行寫入的請求(由此進程或另一進過程發出的請求)都將失敗。但是,即使指定了此標志,仍可能需要附加權限才能夠訪問該文件。
- (1)Delete 允許隨后刪除文件(在一個進程進行讀取某文件時,另一個進程可以同時對該文件進行刪除)。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite);
- FileStream (String, FileMode, FileAccess, FileShare, Int32) 用指定的路徑、創建模式、讀/寫及共享權限和緩沖區大小初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize)
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512);
- FileStream (String, FileMode, FileAccess, FileShare, Int32, Boolean) // 使用指定的路徑、創建模式、讀/寫和共享權限、緩沖區大小和同步或異步狀態初始化FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,bool useAsync) // userAsyn 指定使用異步 I/O 還是同步 I/O。
備注:當異步打開時,BeginRead 和 BeginWrite 方法在執行大量讀或寫時效果更好,但對於少量的讀/寫,這些方法速度可能要慢得多。正確使用異步 I/O,可以使應用程序的速度加快 10 倍,但是如果在沒有為異步 I/O 重新設計應用程序的情況下使用異步 I/O,則可能使性能降低 10 倍。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512 ,true);
- FileStream (String, FileMode, FileAccess, FileShare, Int32, FileOptions) // 使用指定的路徑、創建模式、讀/寫和共享權限、其它 FileStreams 可以具有的對此文件的訪問權限、緩沖區大小和附加文件選項初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,FileOptions options)
FileOptions 成員:
- (1)Asynchronous 指示文件可用於異步讀取和寫入。
- (2)DeleteOnClose 指示當不再使用某個文件時,自動刪除該文件。
- (3)Encrypted 指示文件是加密的,只能通過用於加密的同一用戶帳戶來解密。
- (4)None 指示無其他參數。
- (5)RandomAccess 指示隨機訪問文件。系統可將此選項用作優化文件緩存的提示。
- (6)SequentialScan 指示按從頭到尾的順序訪問文件。系統可將此選項用作優化文件緩存的提示。如果應用程序移動用於隨機訪問的文件指針,可能不發生優化緩存,但仍然保證操作的正確性。 指定此標志可以提高使用順序訪問讀取大文件的應用程序的性能。對於大多數情況下都按順序讀取大文件、但偶爾跳過小的字節范圍的應用程序而言,性能提升可能更明顯。
- (7)WriteThrough 指示系統應通過任何中間緩存、直接寫入磁盤。
- FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512 ,FileOptions.Asynchronous);
- FileStream (String, FileMode, FileSystemRights, FileShare, Int32, FileOptions) 使用指定的路徑、創建模式、訪問權限和共享權限、緩沖區大小和附加文件選項初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileSystemRights rights,FileShare share,int bufferSize,FileOptions options)
FileSystemRights成員:(訪問權限)
- AppendData 指定將數據追加到文件末尾的權限。
- ChangePermissions 指定更改與文件或文件夾關聯的安全和審核規則的權限。
- CreateDirectories 指定創建文件夾的權限。此權限需要 Synchronize 值。請注意,如果在創建文件或文件夾時未顯式設置 Synchronize 值,則會自動為您設置 Synchronize 值。
- CreateFiles 指定創建文件的權限。此權限需要 Synchronize 值。請注意,如果在創建文件或文件夾時未顯式設置Synchronize 值,則會自動為您設置 Synchronize 值。
- Delete 指定刪除文件夾或文件的權限。
- DeleteSubdirectoriesAndFiles 指定刪除文件夾和該文件夾中包含的所有文件的權限。
- ExecuteFile 指定運行應用程序文件的權限。
- FullControl 指定對文件夾或文件進行完全控制以及修改訪問控制和審核規則的權限。此值表示對文件進行任何操作的權限,並且是此枚舉中的所有權限的組合。
- ListDirectory 指定讀取目錄內容的權限。
- Modify 指定讀、寫、列出文件夾內容、刪除文件夾和文件以及運行應用程序文件的權限。此權限包括 ReadAndExecute 權限、Write 權限和 Delete 權限。
- Read 指定以只讀方式打開和復制文件夾或文件的權限。此權限包括 ReadData 權限、
- ReadExtendedAttributes 權限、ReadAttributes 權限和 ReadPermissions 權限。
- ReadAndExecute 指定以只讀方式打開和復制文件夾或文件以及運行應用程序文件的權限。此權限包括 Read 權限和 ExecuteFile 權限。
- ReadAttributes 指定從文件夾或文件打開和復制文件系統屬性的權限。例如,此值指定查看文件創建日期或修改日期的權限。這不包括讀取數據、擴展文件系統屬性或訪問和審核規則的權限。
- ReadData 指定打開和復制文件或文件夾的權限。這不包括讀取文件系統屬性、擴展文件系統屬性或訪問和審核規則的權限。
- ReadExtendedAttributes 指定從文件夾或文件打開和復制擴展文件系統屬性的權限。例如,此值指定查看作者和內容信息的權限。這不包括讀取數據、文件系統屬性或訪問和審核規則的權限。
- ReadPermissions 指定從文件夾或文件打開和復制訪問和審核規則的權限。這不包括讀取數據、文件系統屬性或擴展文件系統屬性的權限。
- Synchronize 指定應用程序是否能夠等待文件句柄,以便與 I/O 操作的完成保持同步。
- Synchronize 值在允許訪問時自動被設置,而在拒絕訪問時自動被排除。創建文件或文件夾的權限需要此值。請注意,如果在創建文件時未顯式設置此值,則會自動為您設置此值。
- TakeOwnership 指定更改文件夾或文件的所有者的權限。請注意:資源的所有者對該資源擁有完全權限。
- Traverse 指定列出文件夾的內容以及運行該文件夾中所包含的應用程序的權限。
- Write 指定創建文件夾和文件以及向文件添加數據或從文件移除數據的權限。此權限包括
- WriteData 權限、AppendData 權限、WriteExtendedAttributes 權限和 WriteAttributes 權限。
- WriteAttributes 指定打開文件系統屬性以及將文件系統屬性寫入文件夾或文件的權限。這不包括寫入數據、擴展屬性以及寫入訪問和審核規則的功能。
- WriteData 指定打開和寫入文件或文件夾的權限。這不包括打開和寫入文件系統屬性、擴展文件系統屬性或訪問和審核規則的權限。
- WriteExtendedAttributes 指定打開文件夾或文件的擴展文件系統屬性以及將擴展文件系統屬性寫入文件夾或文件的權限。這不包括寫入數據、屬性或訪問和審核規則的功能。
- AppendData 指定將數據追加到文件末尾的權限。
- FileStream (String, FileMode, FileSystemRights, FileShare, Int32, FileOptions, FileSecurity) 使用指定的路徑、創建模式、訪問權限和共享權限、緩沖區大小、附加文件選項、訪問控制和審核安全初始化 FileStream 類的新實例。
函數原型:public FileStream (string path,FileMode mode,FileSystemRights rights,FileShare share,int bufferSize,FileOptions options,FileSecurity fileSecurity)
三、<2>FileStream常用的方法:
- Read() //從流中讀取字節塊並將該數據寫入給定緩沖區中。
函數原型:public override int Read (byte[] array,int offset,int count) // 從byte數組的offset位開始寫入count個字節
備注:因為FileStream主要用於讀取字節和字節數組,也就是二進制數據,所以它不能指定編碼格式,但是如果我們用它來讀取有中文的文本的話,我們就會發現它會亂碼,因為默認的編碼是UTF8,所以我們必須用System.Text.Encoding.GetEncoding("GB2312").GetChars()進行轉碼,這樣很麻煩,所以我們通常不用FileStream讀寫有中文的文本。
- byte[] byteArray = new byte[512];
- char[] charArray = new char[512];
- int byteCount = fs.Read(byteArray, 0, 512);
- System.Text.Encoding.GetEncoding("GB2312").GetChars(byteArray,0,byteCount,charArray,0);
- for (int i = 0; i < byteCount; i++)
- {
- MessageBox.Show(charArray[i].ToString());
- }
- ReadByte() // 從文件中讀取一個字節,並將讀取位置提升一個字節。(沒法讀取中文)
函數原型:public override int ReadByte () //返回的字符的ASCII的十進制數,流的末尾讀取則為 -1
- int b = 0;
- while((b = fs.ReadByte())!=-1)
- {
- MessageBox.Show(Convert.ToChar(b).ToString());
- }
- Seek() // 將該流的當前位置設置為給定值。
函數原型:public override long Seek (long offset,SeekOrigin origin) //相對於origin 的點,從此偏移offset個字節處開始查找。(按字節偏移的,而不是字符)
SeekOrigin成員:
- (1)Begin 指定流的開頭。
- (2)Current 指定流內的當前位置。
- (3)End 指定流的結尾。
- (1)Begin 指定流的開頭。
- int b = 0;
- fs.Seek(2, SeekOrigin.Begin); //文件指針偏移到第2個字節
- b = fs.ReadByte();
- MessageBox.Show(Convert.ToChar(b).ToString());
- fs.Seek(-3, SeekOrigin.End); //文件指針從文件末尾往回偏移3個字節
- b = fs.ReadByte();
- MessageBox.Show(Convert.ToChar(b).ToString());
假設文件的內容是:abcdefghijk 那結果就是:c 和 j
- Write() //使用從緩沖區讀取的數據將字節塊寫入該流。
函數原型:public override void Write (byte[] array,int offset,int count) // 將字節數組從offset位開始寫入count個字節
- byte[] byteArray = new byte[] { 97,98,99,100,110,120}; //字節數組
- fs.Write(byteArray, 0, byteArray.Length);
運行結果:abcdnx
- WriteByte() //將一個字節寫入文件流的當前位置。
函數原型:public override void WriteByte (byte value)
- byte b = 97;
- fs.WriteByte(b);
- BeginRead() // 開始異步讀。 (需要設置FileOptions.Asynchronous參數才能進行異步操作)
函數原型:public override IAsyncResult BeginRead (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
參數:numBytes 表示最多讀取的字節數。
userCallback 異步讀操作完成后調用的方法。
stateObject 一個用戶提供的對象,它將該特定的異步讀取請求與其他請求區別開來。
備注:調用BeginRead/BeginWrite/EndRead/EndWrite執行異步時需要在創建FileStream時傳入FileOptions.Asynchronous參數才能獲取真正的IOCP支持,否則BeginXXX方法將會使用默認定義在Stream基類上的實現。Stream基類中BeginXXX方法會使用委托的BeginInvoke方法來發起異步調用——這會使用一個額外的線程來執行任務。雖然當前調用線程立即返回了,但是數據的讀取或寫入操作依舊占用着另一個線程(IOCP支持的異步操作時不需要線程的),因此並沒有任何“節省”,反而還很有可能降低了應用程序的性能,因為額外的線程切換會造成性能損失。
- EndRead() // 等待掛起的異步讀取完成。(需要設置FileOptions.Asynchronous參數才能進行異步操作)
函數原型:public override int EndRead (IAsyncResult asyncResult)- 參數:asyncResult 對所等待的掛起異步請求的引用。
- BeginWrite() // 開始異步寫。(需要設置FileOptions.Asynchronous參數才能進行異步操作)
函數原型:public override IAsyncResult BeginWrite (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
- EndWrite() // 結束異步寫入,在 I/O 操作完成之前一直阻止。(需要設置FileOptions.Asynchronous參數才能進行異步操作)
函數原型:public override void EndWrite (IAsyncResult asyncResult)
- Flush() // 清除該流的所有緩沖區,使得所有緩沖的數據都被寫入到基礎設備。
函數原型:public override void Flush ()
三、<3>FileStream常用的屬性:
- Name // 獲取操作的文件完整地址。
- Length // 獲取整個文件用字節表示的流長度。 (一個中文占2個字節)
- Position // 獲取或設置此流的當前位置。
- CanRead // 獲取當前流是否支持讀取。(如果該流已關閉或是通過只寫訪問方式打開的,則返回false,調用 Read、ReadByte 和 BeginRead 方法將引發 NotSupportedException。)
- CanSeek // 獲取當前流是否支持查找。(如果該流已關閉或是通過只寫訪問方式打開的,則返回false,調用 Length、SetLength、Position 和 Seek 方法將引發 NotSupportedException。)
- CanWrite // 獲取當前流是否支持寫入。(如果該流已關閉或是通過只寫訪問方式打開的,則返回false,調用 SetLength、Write、BeginWrite 或 WriteByte 方法將引發 NotSupportedException。)
- IsAsync // 獲取FileStream 是否異步打開的。
- Handle // 獲取當前 FileStream 對象所封裝文件的操作系統文件句柄。
- SafeFileHandle // 獲取 SafeFileHandle 對象,該對象表示當前 FileStream 對象封裝的文件的操作系統文件句柄。
四、StreamReader/StreamWriter與FileStream的區別
- 一個很大的區別就是:StreamReader/StreamWriter操作的是字符數據(char),而FileStream操作的是字節數據(byte),FileStream與StreamXXXX類的默認編碼都是UTF8,而一個中文字符占2個字符,所以StreamXXXX類常用於文本的打開與保存,而FileStream則用於數據的傳輸。
- FileStream是不能指定編碼(因為它看到的只是文件的二進制形式,當然無所謂編碼),所以如果有中文的文本的話需要轉碼。
- FileStream是一個較底層的類,只能簡單地讀文件到而緩沖區,而StreamXXXX類封裝了一些高級的方法,如ReadLine() (按行讀取)
- FileStream可以指定FileMode、FileAccess、FileShare、FileOptions等各種文件訪問控制權限、共享權限等,大大擴展了文件讀寫的靈活性,而且FileStream還提供了BeginRead/BeginWrite(異步讀寫)的操作方法,用得好的話可以提高10倍操作速度哦!