JavaRush /Java Blog /Random-TW /練習使用 BufferedReader 和 InputStreamReader 類

練習使用 BufferedReader 和 InputStreamReader 類

在 Random-TW 群組發布
你好!今天的講座將分為兩個部分。我們將重複一些之前已經討論過的舊主題,並研究一些新功能:) 練習使用 BufferredReader 和 InputStreamReader 類別 - 1讓我們從第一個開始。重複是學習之母:) 你已經使用過這樣的類別了BufferedReader。我希望你還沒忘記這個命令:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
在進一步閱讀之前,請嘗試記住每個組件 ( System.in, InputStreamReader, BufferedReader) 負責什麼以及需要它們做什麼。發生了嗎?如果沒有,請不要擔心:)如果此時您忘記了某些內容,請再次重新閱讀這篇專為讀者準備的講座。讓我們簡單地記住他們每個人都能做什麼。 System.in是一個用於從鍵盤接收資料的執行緒。原則上,要實現閱讀文本的邏輯,一個就夠了。但是,正如您所記得的,System.in它只能讀取字節,不能讀取字元:
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
如果我們運行這段程式碼並在控制台中輸入字母“Y”,輸出將如下所示:

Й
208
153
10
西里爾字元在記憶體中佔用2個位元組,顯示在螢幕上(數字10是換行符的位元組表示,即按Enter鍵)。讀取位元組是一種樂趣,因此System.in以純粹的形式使用它會很不方便。為了閱讀每個人都能理解的西里爾字母(而不僅僅是),我們使用InputStreamReader以下包裝:
public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
如果我們在控制台中輸入相同的字母“Y”,這次的結果將會不同:

Й
1049
10
InputStreamReader將讀取的兩個位元組(208、153)轉換為單一數字 1049。這是按字元讀取。1049對應的是字母“Y”,很容易驗證:
public class Main {

   public static void main(String[] args) throws IOException {

       char x = 1049;
       System.out.println(x);
   }
}
控制台輸出:

Й
好吧,對於BufferedReader'a(以及一般情況下的 BufferedAnything),緩衝類別用於優化性能。就效能而言,存取資料來源(檔案、控制台、Internet 上的資源)是一項相當昂貴的操作。因此,為了減少此類呼叫的次數,BufferedReader它會讀取資料並將其累積在一個特殊的緩衝區中,以便我們稍後可以從該緩衝區中接收資料。這樣一來,資料來源的呼叫次數就減少了幾倍甚至幾十倍!BufferedReader'a的另一個附加功能及其相對於常規InputStreamReader' 的優勢是一種非常有用的方法readLine(),可以將資料作為整個字串而不是單個數字讀取。當然,這在實現例如大文本時大大增加了便利性。讀取一行的樣子如下:
public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("Пользователь ввел следующий текст:");
       System.out.println(s);
       reader.close();
   }
}

BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
練習使用 BufferredReader 和 InputStreamReader 類別 - 2當然,BufferedReader這是一種非常靈活的機制,讓您不僅可以使用鍵盤進行工作。例如,您可以直接從 Internet 讀取數據,只需將所需的 URL 傳遞給讀取器即可:
public class URLReader {
   public static void main(String[] args) throws Exception {

       URL oracle = new URL("https://www.oracle.com/index.html");
       BufferedReader in = new BufferedReader(
               new InputStreamReader(oracle.openStream()));

       String inputLine;
       while ((inputLine = in.readLine()) != null)
           System.out.println(inputLine);
       in.close();
   }
}
您可以透過傳遞路徑來從檔案中讀取資料:
public class Main {
   public static void main(String[] args) throws Exception {

       FileInputStream fileInputStream = new FileInputStream("testFile.txt");
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

       String str;

       while ((str = reader.readLine()) != null)   {
           System.out.println (str);
       }

       reader.close();
   }
}

System.out 的替換

現在讓我們來看看我們以前從未接觸過的一種有趣的可能性。您可能還記得,System類別中有兩個靜態欄位 -System.inSystem.out。這對孿生兄弟是線程類別物件。System.in- 抽象類別InputStream。一System.outPrintStream。現在我們就具體來說一下System.out。如果我們查看該類別的原始程式碼System,我們會看到:
public final class System {

……………...

public final static PrintStream out = null;

  …………

}
所以,System.out只是一個常規的靜態類別變數System。它沒有什麼魔力:) 該變數out屬於該類別PrintStream。這是一個有趣的問題:為什麼在執行程式碼時,System.out.println()輸出出現在控制台而不是其他地方?有可能以某種方式改變這一點嗎?例如,我們想要從控制台讀取資料並將其寫入文字檔案。是否有可能以某種方式實現這樣的邏輯,而不使用額外的讀取器和寫入器類,而只是使用System.out?仍然盡可能:)雖然變數System.out是由修飾符指定的final,但我們仍然可以做到! 練習使用 BufferredReader 和 InputStreamReader 類別 - 3那我們需要什麼? 首先,我們需要一個新的類別物件PrintStream而不是當前的類別物件。預設安裝在類別中的目前物件System不適合我們:它指向控制台。我們需要建立一個新文件,它將指向一個文字文件作為我們資料的「目的地」。 其次,您需要了解如何為變數指派新值System.out。你不能就那樣做,因為它被標記了final。讓我們從最後開始。該類別System恰好包含我們需要的方法 - setOut()。它將一個物件作為輸入PrintStream並將其設定為輸出點。正是我們所需要的!剩下的就是創建物件了PrintStream。這也很容易做到:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
整個程式碼如下所示:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));

       /*Сохраним текущее meaning System.out в отдельную переменную, чтобы потом
       можно было переключиться обратно на вывод в консоль*/
       PrintStream console = System.out;

       // Присваиваем System.out новое meaning
       System.setOut(filePrintStream);
       System.out.println("Эта строка будет записана в текстовый файл");

       // Возвращаем System.out старое meaning
       System.setOut(console);
       System.out.println("А эта строка - в консоль!");
   }
}
結果,第一行將寫入文字文件,第二行將輸出到控制台:) 您可以將此程式碼複製到 IDE 並運行它。透過開啟文字文件,您將看到所需的行已成功寫入其中:) 講座結束。今天,我們記住瞭如何使用串流和讀者,回顧了它們之間的差異,並了解了System.out我們幾乎每節課都使用的新功能:) 下一堂課見!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION