JavaにおけるBufferedReaderとConsoleとScanner

JavaのBufferedReader vs Console vs Scanner

1. 概要

この記事では、walk through the differences between BufferedReader, Console, and Scanner classes in Javaについて説明します。

各トピックについて詳しく知るには、Java ScannerConsole I/O in JavaBufferedReaderに関する個々の記事をご覧になることをお勧めします。

2. ユーザー入力

コンストラクターに渡される基になるストリームを考えると、文字列、ファイル、システムコンソール(通常はキーボードに接続されている)、ソケットなどのboth BufferedReader and Scanner classes are able to handle a wider range of user input

一方、Consoleクラスは、現在のJava仮想マシンに関連付けられている文字ベースのシステムコンソールにのみアクセスするように設計されています。

さまざまな入力を受け入れるBufferedReaderコンストラクターを見てみましょう。

BufferedReader br = new BufferedReader(
  new StringReader("Bufferedreader vs Console vs Scanner in Java"));
BufferedReader br = new BufferedReader(
  new FileReader("file.txt"));
BufferedReader br = new BufferedReader(
  new InputStreamReader(System.in))

Socket socket = new Socket(hostName, portNumber);
BufferedReader br =  new BufferedReader(
  new InputStreamReader(socket.getInputStream()));

Scannerクラスも同様に、コンストラクターでさまざまな入力を受け入れることができます。

Scanner sc = new Scanner("Bufferedreader vs Console vs Scanner in Java")
Scanner sc = new Scanner(new File("file.txt"));
Scanner sc = new Scanner(System.in);

Socket socket = new Socket(hostName, portNumber);
Scanner sc =  new Scanner(socket.getInputStream());

Consoleクラスは、メソッド呼び出しを介してのみ使用できます。

Console console = System.console();

Consoleクラスを使用する場合、EclipseやIntelliJ IDEAなどのIDE内でコードを実行すると、JVMに関連付けられたシステムコンソールを使用できないことに注意してください。

3. ユーザー出力

readPassword (String fmt, Object… args), readLine (String fmt, Object… args),printf (String format,Object… args)to write the prompt to the system console’s output streamなどのIn contrast to BufferedReader and Scanner classes, which don’t write anything to the output stream, the Console class offers some convenient methods

String firstName = console.readLine("Enter your first name please: ");
console.printf("Welcome " + firstName );

そのため、システムコンソールとやり取りするプログラムを作成する場合、Consoleクラスは、不要なSystem.out.printlnを削除することで、コードを簡素化します。

4. 入力の解析

The Scanner class can parse primitive types and strings using regular expressions

デフォルトの空白に一致するカスタム区切りパターンを使用して、入力をトークンに分割します。

String input = "Bufferedreader vs Console vs Scanner";
Scanner sc = new Scanner(input).useDelimiter("\\s*vs\\s*");
System.out.println(sc.next());
System.out.println(sc.next());
System.out.println(sc.next());
sc.close();

BufferredReaderおよびConsoleクラスは、入力ストリームをそのまま読み取るだけです。

5. 安全なデータの読み取り

ConsoleクラスにはメソッドreadPassword()readPassword (String fmt, Object… args) があり、エコーを無効にして安全なデータを読み取り、ユーザーが入力内容を確認できないようにします。

String password = String.valueOf(console.readPassword("Password :"));

BufferedReaderScannerにはそうする機能がありません。

6. スレッドセーフ

BufferedReaderの読み取りメソッドとConsoleの読み取りメソッドと書き込みメソッドはすべてsynchronizedですが、Scannerクラスのメソッドはそうではありません。 If we read the user input in a multi-threaded program, either BufferedReader or Console will be a better option.

7. バッファサイズ

The buffer size is 8 KB in BufferedReader as compared to 1 KB in Scanner class

さらに、必要に応じて、the BufferedReaderクラスのコンストラクターでバッファーサイズを指定できます。 これは、ユーザー入力から長い文字列を読み取るときに役立ちます。 Console class has no buffer when reading from the system consoleですが、システムコンソールに書き込むためのバッファリングされた出力ストリームがあります。

8. その他

さまざまな状況で使用する適切なクラスを選択する際に考慮する主要な要因ではないいくつかの違いがあります。

8.1. 入力ストリームを閉じる

BufferedReaderまたはScannerのインスタンスを作成したら、remember to close it in order to avoid a memory leakを作成する必要があります。 ただし、これはConsoleクラスでは発生しません。使用後にシステムコンソールを閉じる必要はありません。

8.2. 例外処理

ScannerConsoleは未チェックの例外アプローチを採用していますが、BufferedReaderのメソッドはチェック済みの例外をスローするため、例外を処理するための定型的なtry-catch構文を作成する必要があります。

9. 結論

これらのクラス間の違いについて説明したので、いくつかのrules of thumb regarding which one(s) are best suited to tackle different situationsを考えてみましょう。

  • ファイルから長い文字列を読み取る必要がある場合は、Scannerよりもパフォーマンスが優れているため、BufferedReaderを使用します。

  • システムコンソールから安全なデータを読み取っていて、入力されている内容を非表示にする場合は、Consoleを検討してください

  • カスタム正規表現を使用して入力ストリームを解析する必要がある場合は、Scannerを使用します

  • Scannerは、入力ストリームを読み取って解析するためのきめ細かいメソッドを提供するため、システムコンソールを操作するときに推奨されます。 さらに、ほとんどの場合、nextXXXメソッドがブロックされ、手動入力を待機するため、パフォーマンスの欠点は大きな問題ではありません。

  • スレッドセーフなコンテキストでは、Consoleクラスに固有の機能を使用する必要がない限り、BufferedReaderを検討してください。