1.InputStreamReader

流的另一個有趣的特性是您可以將多個流組合成。一個流不僅可以從它的內部數據源中讀取數據,還可以從另一個流中讀取數據。

這是 Java 中一種非常強大的機制,它可以通過將一個流連接到另一個流來創建複雜的數據讀取場景。這樣的方案看起來像這樣:

InputStreamReader 類

當程序從數據流中讀取數據時,數據流又從其數據源(例如另一個數據流或文件)中讀取數據。

更重要的是,每個數據流不僅可以讀入和發出數據,還可以對其進行轉換或對其進行各種操作。這種“中間流”的一個很好的例子就是類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(),它可以讓您一次從源流中讀取整個數據字符串。例如,您可以使用此方法讀取文件並將其內容逐行顯示在屏幕上。例子:

我們專門寫了一些緊湊的代碼來說明這有多方便。這段代碼也可以寫得更詳細一些。

String src = "c:\\projects\\log.txt";

try(FileReader in = new FileReader(src);
BufferedReader reader = new BufferedReader(in))
{
   while (reader.ready())
   {
      String line = reader.readLine();
      System.out.println(line);
   }
}
創建一個FileReader對象。數據源是一個文件。
創建一個BufferedReader對象。數據源是一個FileReader.
只要閱讀器中還有數據
讀取一行
顯示該行
重要的一點:

如果將多個流鏈接在一起,則只close()需要在其中一個上調用該方法。該流將在其數據源上調用該方法,依此類推,直到close()在最終數據流上被調用。



3.從控制台讀取

還有一個更有趣的事實:該類Scanner只不過是一個從 中讀取數據的中間輸入流System.in,它也是一個數據流。

以下是從控制台讀取一行的兩種方法:

掃描儀類 BufferedReader 和 BufferedWriter 類
InputStream stream = System.in;
Scanner console = new Scanner(stream);
String line = console.nextLine();
InputStream stream = System.in;
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buff = new BufferedReader(reader);
String line = buff.readLine();

我們的朋友只不過是類的靜態變量。這是一個名字是。System.ininSystemInputStreamin

因此,幾乎從您在 CodeGym 上學習 Java 的一開始,您就一直在處理數據流並從中構建鏈。但現在你會更有意識地去做。