Reading Input in Java: Scanner and Console
Scanner is Java's flexible tokenising reader: it reads from stdin, files, strings, or any InputStream, parses tokens by whitespace or a custom delimiter pattern, and provides typed accessors like nextInt() and nextDouble(). Console is a simpler, JVM-provided interface to the terminal that uniquely supports echo-free password input via readPassword(). This article covers both APIs, the common nextLine-after-nextInt pitfall, reading files with Scanner, and when to prefer BufferedReader instead.
Reading from Standard Input with Scanner
ScannerBufferedReaderreadLine()Integer.parseInt()ScannernextInt()Scannernext()nextLine()nextInt()nextDouble()nextBoolean()
Wrap System.inScannerScannerScannerSystem.in
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = sc.nextLine(); // reads a full line including spaces
System.out.print("Enter your age: ");
int age = sc.nextInt(); // reads and parses the next integer token
System.out.print("Enter your GPA: ");
double gpa = sc.nextDouble(); // reads and parses the next double token
System.out.printf("Hello %s, age %d, GPA %.2f%n", name, age, gpa);
sc.close(); // close when done — releases the underlying stream
ScannerSystem.inSystem.inThe nextLine() After nextInt() Pitfall
This is the most common ScannernextInt()nextDouble()next()\nnextLine()
The fix is straightforward: add a sc.nextLine()
Scanner sc = new Scanner(System.in);
System.out.print("Enter quantity: ");
int qty = sc.nextInt();
sc.nextLine(); // ← consume the leftover '\n' from the Enter key
System.out.print("Enter product name: ");
String product = sc.nextLine(); // now correctly waits for user input
System.out.println(qty + " × " + product);
// Alternative: read everything as lines and parse manually
Scanner sc2 = new Scanner(System.in);
System.out.print("Enter quantity: ");
int qty2 = Integer.parseInt(sc2.nextLine().trim());
System.out.print("Enter product name: ");
String product2 = sc2.nextLine();
// No leftover-newline problem because nextLine() always consumes the full line
Note: The "read everything as lines, then parse" pattern avoids the leftover-newline problem entirely and makes error handling easier: you can validate the trimmed string before parsing rather than letting InputMismatchException
Scanning Files and Strings
ScannerFilePathStringInputStreamFiles.lines()BufferedReaderScannerInputStream
Scanning a String
import java.io.File;
import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
// Scan a file — throws FileNotFoundException (checked)
try (Scanner fileScanner = new Scanner(
new File("/data/numbers.txt"), StandardCharsets.UTF_8)) {
while (fileScanner.hasNextInt()) {
int n = fileScanner.nextInt();
System.out.println(n);
}
}
// Scan a Path (Java 10+)
try (Scanner pathScanner = new Scanner(
Path.of("/data/records.csv"), StandardCharsets.UTF_8)) {
pathScanner.useDelimiter(",|\r?\n"); // split on comma or newline
while (pathScanner.hasNext()) {
System.out.println(pathScanner.next().trim());
}
}
// Scan an in-memory String
String csv = "10,20,30,40";
Scanner strScanner = new Scanner(csv).useDelimiter(",");
int sum = 0;
while (strScanner.hasNextInt()) {
sum += strScanner.nextInt();
}
System.out.println("Sum: " + sum); // 100
Files.lines(path)Stream<String>new BufferedReader(new FileReader(file))ScannerConsole: Terminal I/O and Password Input
java.io.ConsoleScannerreadPassword()
The console is obtained via System.console()null
import java.io.Console;
Console console = System.console();
if (console == null) {
System.err.println("No console available — run from a terminal");
System.exit(1);
}
// Read a line with a prompt
String username = console.readLine("Username: ");
// Read a password — characters are NOT echoed to the screen
char[] password = console.readPassword("Password: ");
System.out.println("Logged in as: " + username);
// Process the password as a char[] — clears it from memory when done
// (unlike String, a char[] can be zeroed out explicitly)
boolean valid = authenticate(username, password);
java.util.Arrays.fill(password, '\0'); // zero out after use
// Formatted output directly to the terminal (bypasses any stdout redirect)
console.printf("Welcome, %s!%n", username);
StringreadPassword()char[]Arrays.fill(password, '\0')Scanner vs BufferedReader: When to Use Each
Both ScannerBufferedReaderScannerBufferedReader
Choose ScannerBufferedReaderStream<String>lines()
| Feature | Scanner | BufferedReader |
|---|---|---|
| Typed parsing (nextInt, nextDouble) | ✅ Built-in | ❌ Manual |
| Reading full lines | ✅ nextLine() | ✅ readLine() |
| Stream<String> of lines | ❌ | ✅ lines() |
| Custom delimiter / regex tokenisation | ✅ useDelimiter() | ❌ |
| Performance on large files | Slower (unbuffered by default) | Fast (buffered) |
| Echo-free password input | ❌ | ❌ (use Console) |
| Sources supported | InputStream, File, Path, String, Readable | Reader (wrap FileReader, InputStreamReader) |