.NET C# I/O 操作
本文內(nèi)容
- 流 Stream 和基本操作
- 用于 I/O 的類
- 通用 I/O Stream 類
- I/O 與安全
- 演示
- 如何向文本文件寫(xiě)入字符串
- 如何從文本文件讀取字符串
- 如何讀取數(shù)據(jù)文件
- 如何向字符串寫(xiě)入字符
- 如何從字符串讀取字符
- 參考資料
- 修改記錄
2008 年畢業(yè)時(shí),在解決問(wèn)題時(shí),第一反映是—— baidu 或 google 一下,身邊的很多人都是這么說(shuō)的。當(dāng)然也有人說(shuō),微軟 MSDN 是個(gè)好東西,雖然我當(dāng)時(shí)也知道這點(diǎn),但對(duì)于一個(gè)沒(méi)有多少項(xiàng)目經(jīng)驗(yàn)的人來(lái)說(shuō),使用 MSDN 的確有些困難。因?yàn)槟悴恢廊绾卧?MSDN 中找到解決問(wèn)題的辦法,換句話說(shuō),MSDN 不可能直接告訴你,你的問(wèn)題如何解決。
但 MSDN 對(duì)于一個(gè)求知欲強(qiáng)、善于思考、提升編程能力的人來(lái)說(shuō),是不可或缺的。網(wǎng)上的東西永遠(yuǎn)只是事物的一個(gè)側(cè)面,而 MSDN 卻是知識(shí)的一個(gè)體系。我希望你能明白我的意思:這就好像“信息”和“知識(shí)”的區(qū)別。“信息”只有經(jīng)過(guò)你自己匯總、比較、反思,無(wú)數(shù)次的假設(shè)和無(wú)數(shù)次的否定,才能成為“知識(shí)”——自己的東西。
凡事都有第一次,我最初使用 MSDN 也是迫于無(wú)奈。一是有意識(shí)地去使用 MSDN,再就是因?yàn)樯婷?#xff0c;客戶那不允許上網(wǎng)。在這樣的情況下,我開(kāi)始使用 MSDN。通過(guò)它的鏈接,你可以學(xué)習(xí)到相關(guān)的所有問(wèn)題,加深對(duì)知識(shí)的理解。
下面就要開(kāi)始我的問(wèn)題——.NET I/O 操作。
System.IO 命名空間下,有四種類型的邏輯組:
- 獲取文件和目錄的相關(guān)信息,執(zhí)行與文件和目錄相關(guān)的基本操作;
- 在路徑名上執(zhí)行基本字符串的操作;
- 在數(shù)據(jù)流和文件上進(jìn)行讀寫(xiě)操作;
- 當(dāng)給定的目錄樹(shù)上文件和文件夾發(fā)生動(dòng)態(tài)變化時(shí),獲取相關(guān)通知。
本文主要說(shuō)明前三個(gè)。
抽象基類 Stream 支持讀寫(xiě)字節(jié)。Stream 集成了異步支持。它默認(rèn)的實(shí)現(xiàn)對(duì)相應(yīng)的異步方法定義了同步讀寫(xiě),反之亦然。
所有關(guān)于流(Stream)的類都是從 Stream 類繼承的。Stream 類和其子類提供了數(shù)據(jù)源和存儲(chǔ)的通用視圖,獨(dú)立于操作系統(tǒng)和底層設(shè)備的細(xì)節(jié)。
流 Stream 和基本操作
.NET System.IO 提供了對(duì)兩種截然不同類型的數(shù)據(jù)——流和文件。文件是在磁盤(pán)上持久保存的、有序的并且已命名的字節(jié)集合。流代表從數(shù)據(jù)存儲(chǔ)區(qū)中讀取的或要寫(xiě)入數(shù)據(jù)存儲(chǔ)區(qū)的字節(jié)塊;流可以是基于多種存儲(chǔ)媒體的。所以,流是文件的超集。
Stream 類支持三種基本操作:
- 1. 讀,是將數(shù)據(jù)從流中讀取到數(shù)據(jù)結(jié)構(gòu)中保存,如一個(gè)字節(jié)數(shù)組。
- 2. 寫(xiě),是將數(shù)據(jù)結(jié)構(gòu)中的數(shù)據(jù)寫(xiě)入流中。
- 3. 搜索。包括查詢和修改流中當(dāng)前的位置。
根據(jù)底層數(shù)據(jù)源或存儲(chǔ),流可能只支持上面這些功能。例如,NetworkStreams 不支持定位(seek),這是顯而易見(jiàn)的。Stream 及其子類的 CanRead、CanWrite、和 CanSeek 屬性確定各種流支持的操作。
?
用于 I/O 的類
- 1. Directory 全局靜態(tài)類,提供創(chuàng)建目錄、復(fù)制目錄、移動(dòng)目錄和枚舉目錄中的文件子目錄的靜態(tài)方法。DirectoryInfo 類提供相應(yīng)的實(shí)例方法。
- 2. DirectoryInfo 類,Directory 類提供的是靜態(tài)方法,而 DirectoryInfo 類提供的實(shí)例方法。
- 3. File 全局靜態(tài)類,提供創(chuàng)建文件、復(fù)制文件、刪除文件、移動(dòng)文件、打開(kāi)文件的靜態(tài)方法,并且?guī)椭鷦?chuàng)建一個(gè) FileStream 對(duì)象。FileInfo 類提供實(shí)例方法。
- 4. FileInfo 類,File 類提供的是靜態(tài)方法,而 FileInfo 類提供的是實(shí)例方法。但他們的內(nèi)部實(shí)現(xiàn)和編程接口上是有區(qū)別的。
- 5. DriveInfo 類,提供訪問(wèn)驅(qū)動(dòng)器信息的實(shí)例方法。
- 6. FileStream 類,通過(guò)Seek方法支持隨機(jī)訪問(wèn)文件。默認(rèn)情況下,FileStream 異步打開(kāi)文件,但也支持同步操作。File 包含靜態(tài)方法,而 FileInfo 則包含實(shí)例方法。
- 7. FileSystemInfo 是抽象類,FileInfo 和DirectoryInfo 類繼承該類。
- 8. Path 類,提供的方法和屬性,用于以跨平臺(tái)的方式處理目錄字符串。
- 9. DeflateStream 類,提供的方法和屬性,使用 Deflate 算法壓縮和解壓流。
- 10. GZipStream 類,也是壓縮和解壓流。默認(rèn)情況下,這個(gè)類和 DeflateStream 一樣,但是可以擴(kuò)展使用其他壓縮格式。
- 11. SerialPort 類,提供的方法和屬性,用于控制一個(gè)串口文件資源。
類 File、FileInfo、DriveInfo、Path、Directory 和 DirectoryInfo 都是密封類,你可以創(chuàng)建這些類的實(shí)例,但它們不能被繼承。
- 12. BinaryReader 和 BinaryWriter 類,從流讀寫(xiě)編碼的字符串和基礎(chǔ)數(shù)據(jù)類型。
- 13. StreamReader 類,通過(guò) Encoding 把字符轉(zhuǎn)換成字節(jié),從流中讀取字符串。StreamReader 有一個(gè)構(gòu)造函數(shù),嘗試確定一個(gè)給定流的正確 Encoding。這是基于一個(gè)特定編碼序言,例如一個(gè)字節(jié)順序標(biāo)記。
- 14. StreamWriter 類,通過(guò) Encoding 把字符轉(zhuǎn)換成字節(jié),像流中寫(xiě)入字符。
- 15. StringReader 類,從字符串讀取字符。StringReader 允許你用相同的 API 來(lái)對(duì)待字符串,因此,你的輸出可以是一個(gè)任意編碼的流,或是一個(gè)字符串。
- 16. StringWriter 類,把字符寫(xiě)入到字符串。StringWriter? 允許你用相同的 API 來(lái)對(duì)待字符串,因此,你的輸出可以是一個(gè)任意編碼的流,或是一個(gè)字符串。
- 17. TextReader 類是抽象類,StreamReader 和 StringReader 繼承該類。抽象的 Stream 類的實(shí)現(xiàn)是為了字節(jié)的輸入和輸出設(shè)計(jì)的,而 TextReader 的實(shí)現(xiàn)是為 Unicode 字符輸出設(shè)計(jì)的。
- 18. TextWriter 類是抽象類,StreamWriter 和 StringWriter 繼承該類。抽象的 Stream 類的實(shí)現(xiàn)是為了字節(jié)的輸入和輸出設(shè)計(jì)的,而 TextWriter 的實(shí)現(xiàn)是為 Unicode 字符輸入設(shè)計(jì)的。
?
通用 I/O Stream 類
1. BufferedStream 類,將一個(gè)緩沖區(qū)添加到另一個(gè)流中,比如網(wǎng)絡(luò)流 NetworkStream。(FileStream 已經(jīng)進(jìn)行了內(nèi)部緩沖,MemoryStream 不需要緩沖)BufferedStream 可以有很多類型的流組成,以提高讀寫(xiě)性能。緩沖區(qū)是內(nèi)存中的一個(gè)塊字節(jié)用于緩存數(shù)據(jù),從而減少了操作系統(tǒng)的調(diào)用次數(shù)。
2. CryptoStream 類,將數(shù)據(jù)流鏈接到加密轉(zhuǎn)換的流。盡管它繼承了 Stream,但是并不在 System.IO 命名空間,而是在 System.Security.Cryptography 里。
3. MemoryStream 類,是一個(gè)非緩沖的流,它封裝的數(shù)據(jù)在內(nèi)存中可以直接訪問(wèn)。這個(gè)流沒(méi)有后備存儲(chǔ),作為一個(gè)臨時(shí)緩沖很有用。
4. NetworkStream 類,是一個(gè)網(wǎng)絡(luò)連接的流。盡管它繼承了 Stream 類,但是它并不在 System.IO 命名空間,而是在 System.Net.Sockets 里。
?
I/O 與安全
當(dāng)使用 System.IO 命名空間中的類時(shí),允許的訪問(wèn)必須滿足操作系統(tǒng)的安全需要,如訪問(wèn)控制列表(ACL)。這個(gè)需求除了任何 FileIOPermission 需要的。
備注:ACL 可以由程序管理。For more information, see How to: Add or Remove Access Control List Entries and ACL Technology Overview.
注意:Internet 和 intranet 默認(rèn)的安全策略不允許訪問(wèn)文件。因此,如果你編寫(xiě)需要通過(guò)網(wǎng)絡(luò)下載的代碼,就不能使用正規(guī)的非隔離存儲(chǔ)(nonisolated storage )I/O 類,而應(yīng)該使用隔離存儲(chǔ)(Isolated Storage)。
當(dāng)打開(kāi)一個(gè)文件或是網(wǎng)絡(luò)流,安全檢查只有在流構(gòu)造時(shí)才會(huì)進(jìn)行。因此,當(dāng)向不太受信任的代碼或是應(yīng)用程序域提交這些流是,應(yīng)該謹(jǐn)慎。
以上就是基本文件 I/O 操作的相關(guān)類,看過(guò)之后,你多半還是有些迷糊,但你至少已經(jīng)知道文件 I/O 涉及了哪些方面,如讀、寫(xiě)、字節(jié)數(shù)組、字符串、文件,還有訪問(wèn)控制列表,這些“關(guān)鍵字”就是信息,之后就要靠你自己把這些信息,形成一個(gè)體系——文件 I/O。MSDN 給出了幾個(gè)完整的例子,比如,如何讀寫(xiě)二進(jìn)制文件;如何讀寫(xiě)文本文件;如何讀寫(xiě)字符串等等,我覺(jué)得不錯(cuò)。
?
演示
如何向文本文件寫(xiě)入字符串
例一,演示如何向一個(gè)已經(jīng)存在的文件添加文本;例二,演示如何創(chuàng)建一個(gè)新的文件,并向它寫(xiě)入一個(gè)字符串。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(); } } }如何從文本文件讀取字符串
第二個(gè)例子添加了檢測(cè)文件結(jié)束。通過(guò) ReadAll() 和 ReadAllText() 方法能實(shí)現(xiàn)同樣的功能。
例一
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(); } } }如何讀取數(shù)據(jù)文件
BinaryReader 和 BinaryWriter 類用來(lái)讀寫(xiě)數(shù)據(jù),而不是字符串。下面的例子演示讀寫(xiě)數(shù)據(jù)。
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(); } }說(shuō)明:如果 Test.data 文件在當(dāng)前目錄已經(jīng)存在,會(huì)拋出 IOException 異常。
如何向字符串寫(xiě)入字符
下面的例子演示用 StringWriter 類向一個(gè)字符串寫(xiě)入字符數(shù)組中的字符。
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]
轉(zhuǎn)載于:https://www.cnblogs.com/liuning8023/archive/2011/08/28/2156546.html
總結(jié)
以上是生活随笔為你收集整理的.NET C# I/O 操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Tushare使用教程
- 下一篇: 1.怎样定制VC#DataGrid列标题