輸入流將數據從文件、標准輸入或其他外部輸入設備中加載到內存。輸出流的作用則剛好相反,即將在內存中的數據保存到文件中,或傳輸給輸出設備。輸入流在Java語言中對應於抽象類java.io.InputStream及其子類,輸出流對應於抽象類java.io.OutputStream及其子類。抽象類java.io.InputStream與java.io.OutputStream定義了輸入流和輸出流的基本操作。
因為java.io.InputStream是抽象類,所以不能通過“new InputStream()”的方式構造java.io.InputStream實例對象。但它定義了輸入流的基本操作,如讀數據(read)和關閉輸入流(close)等。System.in是java.io.InputStream類型的變量,對應於標准輸入,主要用於接受鍵盤的輸入。
類java.io.FileInputStream是抽象類java.io.InputStream的子類。創建類java.io.FileInputStream的實例對象,可以通過類java.io.FileInputStream構造方法創建實例對象。對文件內容進行操作的基本步驟如下:
1)創建該文件所對應的輸入/輸出流或讀寫器的實例對象,以獲得相關的系統資源,例如,存放該文件信息的內存空間以及對該文件的控制權限;
2)對該文件進行讀(輸入)/寫(輸出)操作;
3)最後調用close成員方法,關閉文件,以釋放所占用的系統資源。
抽象類java.io.OutputStream是用來處理輸出流的類。它定義了輸出流的各種基本操作,如:輸出數據(write)和關閉輸出流等。System.out是java.io.OutputStream類型的變量,對應於標准輸出,主要用來在控制台窗口中輸出信息。一般在調用抽象類java.io.OutputStream的write成員方法之後,常常會調用抽象類java.io.OutputStream的強制輸出成員方法flush()。這往往是很有必要的,因為目前的計算機系統為提高運行效率,常常采用緩存機制。這樣,在調用成員方法write之後,常常不會將數據直接輸出或寫入文件,而是暫時保存在緩存中。當數據積累到了一定程度時,才會真正往外輸出數據。調用成員方法flush就是為了強制立即輸出數據。這樣,在調用成員方法flush之後,一般馬上就可以看到輸出結果。
類java.io.FileOutputStream是抽象類java.io.OutputStream的子類。創建類java.io.FileOutputStream的實例對象一般通過其構造方法完成,該實例對象可以調用相應的write成員方法將數據寫入文件,並通過close成員方法關閉輸出流。其對文件進行操作的步驟如下:
1)創建類java.io.FileOutputStream的實例對象,以獲得相關的文件資源;
2)通過類java.io.FileOutputStream的write成員方法將數據寫入文件中;在這中間,並通過類java.io.FileOutputStream的flush成員方法強制輸出;
3)最後,調用類java.io.FileOutputStream的close成員方法,關閉文件,以釋放所占用的系統資源。
創建類java.io.FileOutputStream的實例對象以及調用類java.io.FileOutputStream的write成員方法等可能產生異常。因此,一般需要采用try-catch結構或try-catch-finally結構處理相應的異常。
類java.io.PrintStream是非常重要的輸出流類。表示標准輸出並用來在控制台窗口中輸出信息的System.out是java.io.PrintStream類型的變量。類java.io.PrintStream具有非常良好的特性:
1)它包含可以用來直接輸出多種類型數據的不同成員方法;
2)它的大部分成員方法不拋出異常;
3)可以選擇是否采用自動強制輸出(flush)特性。如果采用自動強制輸出特性,則當輸出回車換行時,在緩存中的數據一般會全部自動寫入指定的文件或在控制台窗口中顯示。
數據的輸入流與輸出流對應的類分別是類java.io.DataInputStream與java.io.DataOutputStream,主要用來讀取與存儲基本數據類型的數據,而且每個基本數據類型數據存儲的字節數與它在內存中的占用字節數相同,例如:整數(int)類型的數據占用4個字節。因為數據流的存儲格式采用統一的形式,所以數據的輸入流與輸出流的平台相關性較小。一般說來,輸入流與輸出流在使用上應當相互配套,例如:采用數據輸入流(DataInputStream)讀取數據輸出流(DataOutputStream)存儲的數據。
帶緩存的輸入流和輸出流對應的類是java.io.BufferedInputStream和java.io.BufferedOutputStream。這兩個類通過緩存機制進一步增強了輸入流(Input Stream)和輸出流(Output Stream)讀取和存儲數據的效率。當創建java.io.BufferedInputStream或java.io.BufferedOutputStream的實例對象時,均會在內存中開辟一個字節數組的存儲單元(一般稱為緩存),用來存放在數據流終中的數據。這樣,借助於字節數組緩存,在讀取或存儲數據時可以將一個較大數據塊讀入內存中,或將在內存中較大數據塊一次性寫入指定的文件中,從而達到提高讀/寫效率的目的。
類java.lang.System含有3個靜態成員域in、out和err,分別表示標准輸入流、標准輸出流和標准錯誤輸出流。標准輸入流主要用來接受鍵盤的輸入。標准輸出流是用來在控制台窗口中輸出信息。標准錯誤輸出流是用來在控制台窗口中輸出錯誤提示信息。因為它們都是類java.lang.System的靜態成員域,所以都可以通過類名直接訪問,即System.in、System.out和System.err。它們的類型分別是java.io.InputStream、java.io.PrintStream和java.io.PrintStream,因此可以通過調用這些類的成員方法進行各種操作。
標准輸入流、標准輸出流和標准錯誤輸出流的重定向就是將這些標准輸入流、標准輸出流和標准錯誤輸出流分別與指定的文件建立起對應關系;當需要輸入數據時,數據將從文件中讀取;當需要輸出數據時,數據將寫入文件。
前面說的輸入流和輸出流都是以字節為基本單位訪問文件,可以認為它們所處理的是字節流。而讀寫器則是以字符為基本單位訪問文件的,從而可以認為讀寫器處理的是字符流。
抽象類java.io.Reader和抽象類java.io.Writer規定了讀寫器的一些基本操作。抽象類java.io.Reader用來讀取數據,抽象類java.io.Writer用來存儲數據。
不能直接用“new Reader()”或“new Writer()”生成抽象類java.io.Reader或抽象類java.io.Writer的實例對象,只能通過抽象類的子類生成它們子類的實例對象。
類java.io.FileReader和類java.io.FileWriter分別是抽象類java.io.Reader和抽象類java.io.Writer的子類。類java.io.FileReader兼容抽象類java.io.Reader的所有成員方法,可以進行讀取字符和關閉字符流等操作。類java.io.FileWriter兼容抽象類java.io.Writer的所有成員方法,可以進行輸出單個或多個字符、強制輸出和關閉字符流等操作。
類java.io.BufferedReader、java.io.LineNumberReader和java.io.BufferedWriter是帶緩存的讀寫器類。這些帶緩存的類通過緩存機制進一步增強了讀寫器讀取和存儲數據的效率。類java.io.BufferedReader和類java.io.LineNumberReader繼承抽象類java.io.Reader的所有成員方法,可以進行讀取字符和關閉字符流等操作。類java.io.BufferedWriter繼承抽象類java.io.Writer的所有成員方法,可以進行輸出單個或多個字符、強制輸出和關閉字符流等操作。
類java.io.PrintWriter是非常重要的字符流類。它與類java.io.PrintStream非常類似。類java.io.PrintStream在處理字節時更強一些,而類java.io.PrintWriter在字符處理中具有優越性。與類java.io.PrintStream相似,類java.io.PrintWriter具有非常良好的特性:
1)類java.io.PrintWriter的大部分成員方法不會拋出異常。如果需要檢查是否有錯誤發生可以通過PrintWriter的成員方法public boolean checkError(),當有錯誤發生時,該成員方法返回true;否則,返回false。
2)類java.io.PrintWriter實現了類java.io.PrintStream的所有print成員方法,因此PrintWriter也具有可以直接輸出多種類型數據的不同成員方法。
3)類java.io.PrintWriter的自動強制輸出(flush)功能與類java.io.PrintStream的相應功能有所不同。當采用PrintWriter時,只有了其成員方法println、printf或format才可能自動強制輸出。
類java.io.InputStreamReader和java.io.OutputStreamWriter是從控制台讀入數據的常用功能類,通過這兩個類可以將輸入流和輸出流轉換為相應的讀寫器,從而方便文本數據的處理。
當需要讀取數據的文件不存在時往往不能直接作出判斷,而必須通過異常才能得到這種信息,而類java.io.File很好地解決了這個問題。類java.io.File一般不涉及文件內部的具體內容,而是從整體上對文件進行處理,如獲取各種各樣的文件信息或者刪除文件。類java.io.File不僅可以對文件進行操作,而且還可以對路徑進行操作。