第一篇 初探I/O
對於一個完整意義上的程式,必定包含對資料的處理。這包括一些使用者的輸入,資料檔案的訪問等等。也正因如此,程式中的輸入輸出技術就顯得尤其的重要。
對於一個從C/C++過來的程式員,檔案的輸入輸出是一件十分麻煩的事。即使在I/O中使用了緩衝技術,輸入輸出無論是代碼的複雜程度上,還是程式的運行速度上,都是一個讓程式員頭疼的事。
而,從Java出現以後,這個問題似乎容易了許多。Sun公司在設計Java時使用了裝飾(Decorator)模式對I/O進行設計。程式員可以很方便地通過物件導向的特性使得自己的I/O代碼具有自己所需要的功能。但這其中美中不足的是Java的I/O包java.io的設計是根據Unix/Linux體系對於檔案的管理方式進行設計的(在Unix/Linux中無論是資料檔案、目錄、硬體裝置都是以檔案的形式進行管理的,整個檔案形式中有且只有一個根‘/’目錄。這種管理方式在某種程度上大大降低管理的複雜度和難度。),對於已經熟悉了Windows檔案管理模式的程式員而言,這顯得十分不便。
現在,在.net平台中也提供了類似於Java的I/O庫。尤其是.Net 2.0庫對I/O修改,使得.Net I/O從抄襲Java的陰影中走出來。
下面就來看看.Net的I/O庫:
1、I/O庫的基本架構
(1)、在.Net中I/O庫被存放在mscorlib.dll檔案中,命名空間是System.IO。其包含五個基本的抽象類別,甚至分別為
Stream:負責對I/O進行流操作,它也是.Net I/O的核心類。基本上所有的I/O操作都離不開它。
TextReader和TextWriter:提供對字元文本操作的抽象類別。
FileSystemInfo:這是.Net 2.0中不同於Java的一個類。它主要負責對檔案資訊的管理,這不僅僅是Windows作業系統中一般意義上的檔案資訊,這還包括目錄等。這進一步增強了對檔案資訊的操作。
IOException:這是I/O庫中對I/O異常進行處理的類。
(2)、下面介紹一下其基本的繼承關係
a)、檔案操作流類Stream:
繼承圖:Stream
FileStream(一般檔案流)
BufferedStream(帶緩衝的檔案流,本人強烈建議使用。)
MemoryStream(對一塊記憶體地區進行託管流的操作)
UnmanagedMemoryStream(對一塊記憶體地區進行非託管流的操作)
b)、文本類TextReader和TextWriter:
繼承圖:TextReader
StreamReader(文字檔流讀操作類)
StringReader(對String類型以檔案的方式進行讀操作的類)
TextWriter
StreamWriter(文字檔流寫操作類)
StringWriter(對StringBuilder類型以檔案的方式進行寫操作的類)
c)、異常類IOException:
繼承圖:IOException
DirectoryNotFoundException(檔案夾未找到異常)
DriveNotFoundException(磁碟機未找到異常)
EndOfStreamException(流結束異常)
FileLoadException(檔案載入異常)
FileNotFoundException(檔案未找到異常)
PathTooLongException(路徑太長異常)
d)、檔案資訊類FileSystemInfo:
繼承圖:FileSystemInfo
FileInfo(檔案資訊類)
DirectoryInfo(目錄資訊類)
e)、其它類:
BinaryReader和BinaryWriter,這是一個對檔案流(Stream)進行二進位操作的類。它直接繼承至Object類,但使用時必須使用流開啟檔案。
File類,對檔案進行操作的類,它提供了大量有用的靜態方法,這是一個方法類。
Directory類,對目錄進行操作的類,包括取得目錄下檔案,建立目錄、刪除目錄等等。
Path類,對路徑進行操作。
DriveInfo類,這個類雖然以Info命名,但並非從FileSystemInfo中繼承而來。這個類也是一個Windows特色類。若使用Mono開發在Linux平台上啟動並執行.Net程式,其就失去了意義。它的主要功能是:取得磁碟機的大小、可用空間、卷標、格式等等。
(3)、關於檔案操作的四個基本抽象類別的基類MarshalByRefObject
這是一個將I/O操作通過使用代理交換訊息來跨應用程式定義域邊界進行通訊的對象的基類。
下面是MSDN上關於這個類的講解:
應用程式定義域是一個作業系統進程中一個或多個應用程式所駐留的分區。同一應用程式定義域中的對象直接通訊。不同應用程式定義域中的對象的通訊方式有兩種:一種是跨應用程式定義域邊界傳輸對象副本,一種是使用代理交換訊息。
MarshalByRefObject是通過使用代理交換訊息來跨應用程式定義域邊界進行通訊的對象的基類。不是從 MarshalByRefObject繼承的對象根據值隱式封送。當遠程應用程式引用根據值封送的對象時,將跨應用程式定義域邊界傳遞該對象的副本。
MarshalByRefObject對象在本地應用程式定義域的邊界內可直接存取。遠程應用程式定義域中的應用程式首次訪問 MarshalByRefObject時,會向該遠程應用程式傳遞代理。對該代理後面的調用將封送回駐留在本地應用程式定義域中的對象。
當跨應用程式定義域邊界使用類型時,類型必須是從 MarshalByRefObject繼承的,而且由於對象的成員在建立它們的應用程式定義域之外無法使用,所以不得複製對象的狀態。
2、.Net I/O中一些有用的功能
這甚時不對I/O進行詳細的介紹,只介紹一些有用的功能。
(1)、取得文字檔的所有行
在File類中有一個方法ReadAllLines(String path, Encoding encoding),可以將文字檔中所有行取出。
(2)、以字串的形式取得文字檔的內容ReadAllText(String path, Encoding encoding)
(3)、以位元組數組的形式取得檔案的內容ReadAllBytes(String path)
(4)、以上操作的寫操作
WriteAllBytes(string path, byte[] bytes);
WriteAllLines(string path, string[] contents, Encoding encoding);
WriteAllText(string path, string contents, Encoding encoding);
(5)向檔案中追加文本
AppendAllText(string path, string contents, Encoding encoding);
(6)取得某路徑下的所有目錄
GetDirectories(string path, string searchPattern, SearchOption searchOption);
(7)取得某路徑下的所有檔案
GetFiles(string path, string searchPattern, SearchOption searchOption);
在.Net中為程式員提供了很多很方便的I/O方法,有時間的話可以好好研究File、Directory、DriveInfo,你會有其他的收穫。