1.InputStreamReader
類
流的另一個有趣的特性是您可以將多個流組合成鏈。一個流不僅可以從它的內部數據源中讀取數據,還可以從另一個流中讀取數據。
這是 Java 中一種非常強大的機制,它可以通過將一個流連接到另一個流來創建複雜的數據讀取場景。這樣的方案看起來像這樣:
當程序從數據流中讀取數據時,數據流又從其數據源(例如另一個數據流或文件)中讀取數據。
更重要的是,每個數據流不僅可以讀入和發出數據,還可以對其進行轉換或對其進行各種操作。這種“中間流”的一個很好的例子就是類InputStreamReader
。
我們已經知道一個名為的類FileReader
——它是一個Reader
從文件中讀取數據的類。從哪裡InputStreamReader
獲取數據?沒錯——來自InputStream
.
當你創建一個InputStreamReader
對象時,你需要傳入一個InputStream
對像或者它的一個子類。例子:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
該類InputStreamReader
具有該類所具有的所有方法Reader
,並且它們以完全相同的方式工作。
InputStreamReader
類和類之間的主要區別FileReader
在於它們從何處讀取數據。FileReader
從文件中讀取數據(呃——這就是它被稱為 的原因FileReader
),InputStreamReader
但從InputStream
.
當您FileReader
使用該read()
方法從對像中讀取一個字符時,它會依次從磁盤上的文件中讀取兩個字節並將它們作為chars
.
當您InputStreamReader
使用該read()
方法從對像中讀取一個字符時,它會依次從FileInputStream
傳遞給它的對像中讀取兩個字節,然後再從文件中讀取數據。結果是對方法的調用鏈read()
。
2.BufferedReader
類
您可能會經常使用的另一個有趣的類是BufferedReader
. 這也是從另一個流中讀取數據的“中間流”。
顧名思義,該類BufferedReader
是 的子類Reader
,可讓您閱讀 characters。但最有趣的是,您還需要以流的形式向它傳遞一個數據源,可以從中讀取字符,即繼承該類的流Reader
。
重點是什麼?與 不同InputStreamReader
,該類BufferedReader
不會將字節轉換為字符:它根本不會轉換任何內容。相反,它緩衝數據。
當程序從對像中讀取單個字符時BufferedReader
,該對象會同時從其源流中讀取大量字符。並將它們存儲在內部。
當從對像中讀取下一個字符時BufferedReader
,它只是從其內部緩衝區數組中獲取下一個字符並返回它,而無需訪問數據源。只有當緩衝區中的所有字符都用完時,它才會讀入另一個大字符數組。
該類BufferedReader
還有一個非常有用的方法 — String readLine()
,它可以讓您一次從源流中讀取整個數據字符串。例如,您可以使用此方法讀取文件並將其內容逐行顯示在屏幕上。例子:
我們專門寫了一些緊湊的代碼來說明這有多方便。這段代碼也可以寫得更詳細一些。
|
創建一個FileReader 對象。數據源是一個文件。創建一個 BufferedReader 對象。數據源是一個FileReader . 只要閱讀器中還有數據 讀取一行 顯示該行 |
如果將多個流鏈接在一起,則只close()
需要在其中一個上調用該方法。該流將在其數據源上調用該方法,依此類推,直到close()
在最終數據流上被調用。
3.從控制台讀取
還有一個更有趣的事實:該類Scanner
只不過是一個從 中讀取數據的中間輸入流System.in
,它也是一個數據流。
以下是從控制台讀取一行的兩種方法:
掃描儀類 | BufferedReader 和 BufferedWriter 類 |
---|---|
|
|
我們的朋友只不過是類的靜態變量。這是一個名字是。System.in
in
System
InputStream
in
因此,幾乎從您在 CodeGym 上學習 Java 的一開始,您就一直在處理數據流並從中構建鏈。但現在你會更有意識地去做。