.NET C# I/O 操作
本文內容
- 流 Stream 和基本操作
- 用于 I/O 的類
- 通用 I/O Stream 類
- I/O 與安全
- 演示
- 如何向文本文件寫入字符串
- 如何從文本文件讀取字符串
- 如何讀取數據文件
- 如何向字符串寫入字符
- 如何從字符串讀取字符
- 參考資料
- 修改記錄
2008 年畢業時,在解決問題時,第一反映是—— baidu 或 google 一下,身邊的很多人都是這么說的。當然也有人說,微軟 MSDN 是個好東西,雖然我當時也知道這點,但對于一個沒有多少項目經驗的人來說,使用 MSDN 的確有些困難。因為你不知道如何在 MSDN 中找到解決問題的辦法,換句話說,MSDN 不可能直接告訴你,你的問題如何解決。
但 MSDN 對于一個求知欲強、善于思考、提升編程能力的人來說,是不可或缺的。網上的東西永遠只是事物的一個側面,而 MSDN 卻是知識的一個體系。我希望你能明白我的意思:這就好像“信息”和“知識”的區別。“信息”只有經過你自己匯總、比較、反思,無數次的假設和無數次的否定,才能成為“知識”——自己的東西。
凡事都有第一次,我最初使用 MSDN 也是迫于無奈。一是有意識地去使用 MSDN,再就是因為涉密,客戶那不允許上網。在這樣的情況下,我開始使用 MSDN。通過它的鏈接,你可以學習到相關的所有問題,加深對知識的理解。
下面就要開始我的問題——.NET I/O 操作。
System.IO 命名空間下,有四種類型的邏輯組:
- 獲取文件和目錄的相關信息,執行與文件和目錄相關的基本操作;
- 在路徑名上執行基本字符串的操作;
- 在數據流和文件上進行讀寫操作;
- 當給定的目錄樹上文件和文件夾發生動態變化時,獲取相關通知。
本文主要說明前三個。
抽象基類 Stream 支持讀寫字節。Stream 集成了異步支持。它默認的實現對相應的異步方法定義了同步讀寫,反之亦然。
所有關于流(Stream)的類都是從 Stream 類繼承的。Stream 類和其子類提供了數據源和存儲的通用視圖,獨立于操作系統和底層設備的細節。
流 Stream 和基本操作
.NET System.IO 提供了對兩種截然不同類型的數據——流和文件。文件是在磁盤上持久保存的、有序的并且已命名的字節集合。流代表從數據存儲區中讀取的或要寫入數據存儲區的字節塊;流可以是基于多種存儲媒體的。所以,流是文件的超集。
Stream 類支持三種基本操作:
- 1. 讀,是將數據從流中讀取到數據結構中保存,如一個字節數組。
- 2. 寫,是將數據結構中的數據寫入流中。
- 3. 搜索。包括查詢和修改流中當前的位置。
根據底層數據源或存儲,流可能只支持上面這些功能。例如,NetworkStreams 不支持定位(seek),這是顯而易見的。Stream 及其子類的 CanRead、CanWrite、和 CanSeek 屬性確定各種流支持的操作。
?
用于 I/O 的類
- 1. Directory 全局靜態類,提供創建目錄、復制目錄、移動目錄和枚舉目錄中的文件子目錄的靜態方法。DirectoryInfo 類提供相應的實例方法。
- 2. DirectoryInfo 類,Directory 類提供的是靜態方法,而 DirectoryInfo 類提供的實例方法。
- 3. File 全局靜態類,提供創建文件、復制文件、刪除文件、移動文件、打開文件的靜態方法,并且幫助創建一個 FileStream 對象。FileInfo 類提供實例方法。
- 4. FileInfo 類,File 類提供的是靜態方法,而 FileInfo 類提供的是實例方法。但他們的內部實現和編程接口上是有區別的。
- 5. DriveInfo 類,提供訪問驅動器信息的實例方法。
- 6. FileStream 類,通過Seek方法支持隨機訪問文件。默認情況下,FileStream 異步打開文件,但也支持同步操作。File 包含靜態方法,而 FileInfo 則包含實例方法。
- 7. FileSystemInfo 是抽象類,FileInfo 和DirectoryInfo 類繼承該類。
- 8. Path 類,提供的方法和屬性,用于以跨平臺的方式處理目錄字符串。
- 9. DeflateStream 類,提供的方法和屬性,使用 Deflate 算法壓縮和解壓流。
- 10. GZipStream 類,也是壓縮和解壓流。默認情況下,這個類和 DeflateStream 一樣,但是可以擴展使用其他壓縮格式。
- 11. SerialPort 類,提供的方法和屬性,用于控制一個串口文件資源。
類 File、FileInfo、DriveInfo、Path、Directory 和 DirectoryInfo 都是密封類,你可以創建這些類的實例,但它們不能被繼承。
- 12. BinaryReader 和 BinaryWriter 類,從流讀寫編碼的字符串和基礎數據類型。
- 13. StreamReader 類,通過 Encoding 把字符轉換成字節,從流中讀取字符串。StreamReader 有一個構造函數,嘗試確定一個給定流的正確 Encoding。這是基于一個特定編碼序言,例如一個字節順序標記。
- 14. StreamWriter 類,通過 Encoding 把字符轉換成字節,像流中寫入字符。
- 15. StringReader 類,從字符串讀取字符。StringReader 允許你用相同的 API 來對待字符串,因此,你的輸出可以是一個任意編碼的流,或是一個字符串。
- 16. StringWriter 類,把字符寫入到字符串。StringWriter? 允許你用相同的 API 來對待字符串,因此,你的輸出可以是一個任意編碼的流,或是一個字符串。
- 17. TextReader 類是抽象類,StreamReader 和 StringReader 繼承該類。抽象的 Stream 類的實現是為了字節的輸入和輸出設計的,而 TextReader 的實現是為 Unicode 字符輸出設計的。
- 18. TextWriter 類是抽象類,StreamWriter 和 StringWriter 繼承該類。抽象的 Stream 類的實現是為了字節的輸入和輸出設計的,而 TextWriter 的實現是為 Unicode 字符輸入設計的。
?
通用 I/O Stream 類
1. BufferedStream 類,將一個緩沖區添加到另一個流中,比如網絡流 NetworkStream。(FileStream 已經進行了內部緩沖,MemoryStream 不需要緩沖)BufferedStream 可以有很多類型的流組成,以提高讀寫性能。緩沖區是內存中的一個塊字節用于緩存數據,從而減少了操作系統的調用次數。
2. CryptoStream 類,將數據流鏈接到加密轉換的流。盡管它繼承了 Stream,但是并不在 System.IO 命名空間,而是在 System.Security.Cryptography 里。
3. MemoryStream 類,是一個非緩沖的流,它封裝的數據在內存中可以直接訪問。這個流沒有后備存儲,作為一個臨時緩沖很有用。
4. NetworkStream 類,是一個網絡連接的流。盡管它繼承了 Stream 類,但是它并不在 System.IO 命名空間,而是在 System.Net.Sockets 里。
?
I/O 與安全
當使用 System.IO 命名空間中的類時,允許的訪問必須滿足操作系統的安全需要,如訪問控制列表(ACL)。這個需求除了任何 FileIOPermission 需要的。
備注:ACL 可以由程序管理。For more information, see How to: Add or Remove Access Control List Entries and ACL Technology Overview.
注意:Internet 和 intranet 默認的安全策略不允許訪問文件。因此,如果你編寫需要通過網絡下載的代碼,就不能使用正規的非隔離存儲(nonisolated storage )I/O 類,而應該使用隔離存儲(Isolated Storage)。
當打開一個文件或是網絡流,安全檢查只有在流構造時才會進行。因此,當向不太受信任的代碼或是應用程序域提交這些流是,應該謹慎。
以上就是基本文件 I/O 操作的相關類,看過之后,你多半還是有些迷糊,但你至少已經知道文件 I/O 涉及了哪些方面,如讀、寫、字節數組、字符串、文件,還有訪問控制列表,這些“關鍵字”就是信息,之后就要靠你自己把這些信息,形成一個體系——文件 I/O。MSDN 給出了幾個完整的例子,比如,如何讀寫二進制文件;如何讀寫文本文件;如何讀寫字符串等等,我覺得不錯。
?
演示
如何向文本文件寫入字符串
例一,演示如何向一個已經存在的文件添加文本;例二,演示如何創建一個新的文件,并向它寫入一個字符串。WriteAllText 方法也提供類似的功能。
例一
using System; using System.IO; class Test { public static void Main() { using (StreamWriter sw = new StreamWriter("TestFile.txt")) { sw.Write("This is the "); sw.WriteLine("header for the file."); sw.WriteLine("-------------------"); sw.Write("The date is: "); sw.WriteLine(DateTime.Now); } } }例二
using System; using System.IO; public class TextToFile { private const string FILE_NAME = "MyFile.txt"; public static void Main(String[] args) { if (File.Exists(FILE_NAME)) { Console.WriteLine("{0} already exists.", FILE_NAME); return; } using (StreamWriter sw = File.CreateText(FILE_NAME)) { sw.WriteLine ("This is my file."); sw.WriteLine ("I can write ints {0} or floats {1}, and so on.", 1, 4.2); sw.Close(); } } }如何從文本文件讀取字符串
第二個例子添加了檢測文件結束。通過 ReadAll() 和 ReadAllText() 方法能實現同樣的功能。
例一
using System; using System.IO; class Test { public static void Main() { try { using (StreamReader sr = new StreamReader("TestFile.txt")) { String line; while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } } } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } } }例二
using System; using System.IO; public class TextFromFile { private const string FILE_NAME = "MyFile.txt"; public static void Main(String[] args) { if (!File.Exists(FILE_NAME)) { Console.WriteLine("{0} does not exist.", FILE_NAME); return; } using (StreamReader sr = File.OpenText(FILE_NAME)) { String input; while ((input=sr.ReadLine())!=null) { Console.WriteLine(input); } Console.WriteLine ("The end of the stream has been reached."); sr.Close(); } } }如何讀取數據文件
BinaryReader 和 BinaryWriter 類用來讀寫數據,而不是字符串。下面的例子演示讀寫數據。
using System; using System.IO; class MyStream { private const string FILE_NAME = "Test.data"; public static void Main(String[] args) { if (File.Exists(FILE_NAME)) { Console.WriteLine("{0} already exists!", FILE_NAME); return; } FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew); BinaryWriter w = new BinaryWriter(fs); for (int i = 0; i < 11; i++) { w.Write( (int) i); } w.Close(); fs.Close(); fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read); BinaryReader r = new BinaryReader(fs); for (int i = 0; i < 11; i++) { Console.WriteLine(r.ReadInt32()); } r.Close(); fs.Close(); } }說明:如果 Test.data 文件在當前目錄已經存在,會拋出 IOException 異常。
如何向字符串寫入字符
下面的例子演示用 StringWriter 類向一個字符串寫入字符數組中的字符。
using System; using System.IO; using System.Text; public class CharsToStr { public static void Main(String[] args) { StringBuilder sb = new StringBuilder("Some number of characters"); char[] b = {' ','t','o',' ','w','r','i','t','e',' ','t','o','.'}; StringWriter sw = new StringWriter(sb); sw.Write(b, 0, 3); Console.WriteLine(sb); sw.Close(); } }如何從字符串讀取字符
下面的例子演示用StringRead類從字符串讀取字符。
using System; using System.IO; public class CharsFromStr { public static void Main(String[] args) { String str = "Some number of characters"; char[] b = new char[24]; StringReader sr = new StringReader(str); sr.Read(b, 0, 13); Console.WriteLine(b); sr.Close(); } }?
?
參考資料
- System.IO 命名空間
- MSDN 文件和流 I/O
- MSDN 文件 I/O(C#與Java)
- MSDN 異步文件 I/O
- VS 2012 使用 Async 和 Await 的 異步編程
?
修改記錄
- 2015-1-17 [add]
轉載于:https://www.cnblogs.com/liuning8023/archive/2011/08/28/2156546.html
總結
以上是生活随笔為你收集整理的.NET C# I/O 操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tushare使用教程
- 下一篇: java-XML