Java: String von der Kommandozeile lesen (mit java.util.Scanner)

Warum ist das Einlesen eines Strings von der Kommandozeile in Java so kompliziert?

war eine Frage die mir heute gestellt wurde. Fragt man Google nach einer Lösung um einen String einzulesen wird meist so etwas unter den ersten Treffern landen:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();

Mit Hilfe von BufferedReader und InputStreamReader kann man nach dem gleichen Prinzip sowohl einen String aus einer Datei, von der Kommandozeile oder jedem beliebigen Stream lesen. Wenn man es häufig genug anwendet, braucht man da gar nicht mehr gros zu überlegen.

Dies ist allerdings doch recht viel Code, wenn man bedenkt das man in C# mit dieser Zeile auskommt:

string input = Console.ReadLine();

 
Scanner als Alternative
Seit Java 5 gibt es die Klasse java.util.Scanner, die man auch zum einlesen von Werten aus der Kommandozeile nutzen kann:

Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();

Es sind zwar auch 2 Zeilen Code, doch braucht man keine InputStreams und *Reader zu kombinieren. Für Strings ist der Vorteil wohl zu wenig gross, sonst würde nicht in so vielen Schulungsunterlagen die Variante mit dem BufferedReader erklärt.

 
Und Zahlen?
Der Scanner ermöglicht die Prüfung ob der nächste Wert vom gewünschten Datentyp ist. So genügt es den Scanner zu fragen und man spart sich den Aufwand den Wert selber zu überprüfen:

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);

		if (scanner.hasNextDouble()) {
			System.out.println("Ihre Zahl: " + scanner.nextDouble());
		} else {
			System.out.println("Leider kein Double gefunden.");
		}
	}

Ich finde dies deutlich angenehmer als mit dem BufferedReader-Ansatz und einer eigenen Validierungsmethode:

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String input = in.readLine();
		
		if (isDouble(input)) {
			double x = Double.valueOf(input).doubleValue();
			System.out.println("Ihre Zahl: " + x);
		} else {
			System.out.println("Leider kein Double gefunden.");
		}
	}

	public static boolean isDouble(String string) {
		try {
			Double.valueOf(string);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}

Vergisst man vor der Konvertierung zu prüfen ob es auch wirklich ein gültiger Wert ist, läuft man sehr schnell in diese Fehlermeldung:

Exception in thread "main" java.lang.NumberFormatException: For input string: "h"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.valueOf(Unknown Source)
at ch.jgraber.blog.DemoTraditionalReadLine.main(DemoTraditionalReadLine.java:18)

 
Fazit
Java bietet mit java.util.Scanner eine einfache Möglichkeit um Strings oder Zahlen von der Kommandozeile zu lesen. Mir scheint als ob diese einfache Möglichkeit bisher zu wenig Beachtung findet. Suche ich nur falsch oder ist dies wirklich so?

Advertisements