Scanner vs. BufferedReader

Viewed 290280

As far I know, the two most common methods of reading character-based data from a file in Java is using Scanner or BufferedReader. I also know that the BufferedReader reads files efficiently by using a buffer to avoid physical disk operations.

My questions are:

  • Does Scanner perform as well as BufferedReader?
  • Why would you choose Scanner over BufferedReader or vice versa?
12 Answers

Scanner is used for parsing tokens from the contents of the stream while BufferedReader just reads the stream and does not do any special parsing.

In fact you can pass a BufferedReader to a scanner as the source of characters to parse.

In currently latest JDK 18 release/build (b37), the Scanner has a smaller buffer (1024 chars) as opposed to the BufferedReader (8192 chars), but it's more than sufficient.

As to the choice, use the Scanner if you want to parse the file, use the BufferedReader if you want to read the file line by line. Also see the introductory text of their aforelinked API documentations.

  • Parsing = interpreting the given input as tokens (parts). It's able to give back you specific parts directly as int, string, decimal, etc. See also all those nextXxx() methods in Scanner class.
  • Reading = dumb streaming. It keeps giving back you all characters, which you in turn have to manually inspect if you'd like to match or compose something useful. But if you don't need to do that anyway, then reading is sufficient.

The difference between BufferedReader and Scanner are following:

  1. BufferedReader is synchronized but Scanner is not synchronized.
  2. BufferedReader is thread-safe but Scanner is not thread-safe.
  3. BufferedReader has larger buffer memory but Scanner has smaller buffer memory.
  4. BufferedReader is faster but Scanner is slower in execution.
  5. Code to read a line from the console:

BufferedReader:

InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String st = br.readLine();
       
// You can make the object InputStreamReader object inside the BufferReader method.
BufferReader br = new BufferedReader(InputStreamReader(System.in));
String st = br.readLine();

// You can even inspect the type of the input stream manually by using Parse method which accepts string parameter.
int x = Integer.parseInt(br.readLine());

// Or you can pass the object directly.
int x = Integer.parseInt(st);

Scanner:

Scanner sc = new Scanner(System.in);
String st = sc.nextLine();
  1. BufferedReader will probably give you better performance (because Scanner is based on InputStreamReader, look sources). oops, for reading data from files it uses nio. When I tested nio performance against BufferedReader performance for big files nio shows a bit better performance.
  2. For reading data from a file try Apache Commons IO.
Related