Wie kann man mit Hilfe der Klasse Scanner Daten von der Konsole oder aus einer Datei lesen? v.5.0
Scanner
kann Text aus jedem Objekt lesen, das das
Interface Readable
implementiert. Das erste
Beispiel demonstriert das Einlesen von der Konsole, dem
Standard-Eingabestrom System.in
. Die hier auf der
Kommandozeile eingegebenen und mit <Return>
abgeschlossenen Texte werden so lange eingelesen und wieder
ausgegeben, bis ein 'q' als Einzelzeichen eingegeben wurde.
Hierzu
wird dem Konstruktor
des Scanner
-Objektes als Quelle der Eingabestrom System.in
übergeben. In einer Endlosschleife wird durch die Methode next()
der String übernommen und auf die o.a. Abbruchbedingung
geprüft. Ist diese erfüllt, so wird die Schleife
verlassen, ein Gruß ausgegeben und das Programm beendet.
Im anderen Fall läuft die Schleife weiter und die
nächste Eingabe wird ausgegeben. Wichtig ist, dass der Scanner
zum Schluss mit close()
geschlossen wird.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true){
String s = scanner.next();
if(s.equals("q")) break;
System.out.println(s);
}
System.out.println("Bye...");
scanner.close();
}
}
Das zweite Beispiel zeigt wie Scanner
aus einer
Textdatei liest und dabei zwischen numerischen und nicht
numerischen Werten unterscheiden kann.
Hierzu muss dem Scanner
-Objekt
ein File
-Objekt übergeben werden. Es
erhält seinerseits den Pfad zur Datei als String
.
Als zweiter, optionaler Parameter kann dem Konstruktor ein
String des Zeichensatzes der Datei übergeben werden.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Locale;
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
Scanner scanner;
try {
scanner = new Scanner(new File("test.txt"),
"UTF-8");
scanner.useLocale(Locale.GERMANY);
int i;
double d;
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
i = scanner.nextInt();
System.out.println("Int: " + ++i);
}else if (scanner.hasNextDouble()) {
d = scanner.nextDouble();
System.out.println("Double: " + ++d);
} else {
System.out.println("String: " + scanner.next());
}
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Scanner
deklariert die Methode hasNext()
.
Sie liefert so lange true
wie weitere Elemente
ausgelesen werden können. Somit lässt sie sich als
Abbruchbedingung in einer while
-Schleife einsetzen,
in der der Inhalt der Datei elementweise ausgegeben wird.
'Elemente'
sind in der Standardeinstellung durch Leerzeichen voneinander
getrennte lesbare Strukturen, bei konventionellen Texten somit
die einzelnen Wörter. Die Leerzeichen selbst werden jedoch
nicht mit zurückgegeben.
Die Klasse Scanner
kennt eine ganze Reihe teilweise
überladener hasNextXX()
- und nextXX()
-Methoden.
XX bezeichnet hier Platzhalter für verschiedene
Datentypen, auf die die Methoden prüfen können. Die
Methoden hasNextXX()
liefern, wie oben
demonstriert, boolsche Werte, die im Beispiel als Filter
eingesetzt werden. Die Methode hasNextInt()
prüft hierbei auf mögliche Integer-Werte, die durch nextInt()
ermittelt, hier inkrementiert und dann ausgegeben werden.
Ähnlich verhält es sich mit hasNextDouble()
.
Trifft keine der beiden Bedingungen zu, so wird das Element als
String
behandelt.
Enthält die ausgelesene Datei den folgenden Eintrag
1 071 1.23 Dies 0xF3 ist 1,4 ein Test
so zeigt das Ergebnis:
Int: 2 Int: 72 String: 1.23 String: Dies String: 0xF3 String: ist Double: 2.4 String: ein String: Test
Hieran lässt sich zweierlei gut erkennen:
- Andere als dezimale Integer-Werte werden nicht automatisch
als solche erkannt. Dies kann auch nicht innerhalb der
Methoden
hasNextInt(int radix)
undnextInt(int radix)
durch die Angabe vonradix
erreicht werden, da die Methoden lediglich die bereits erkannten Integer entsprechend bewerten, auf die Erkennung selbst jedoch keinen Einfluss haben. - Bei der Behandlung von Integer-Werten wird ohne gesonderte
Angabe von
radix
von der Basis 10 ausgegangen. Das Literal071
wird trotz der führenden0
nicht oktal sondern dezimal interpretiert.
Ein Scanner-Objekt besitzt eine Lokalisierungs-Eigenschaft, die
die zugrunde liegende Behandlung von regulären
Ausdrücken erheblich beeinflusst. Man erkennt dies im
Beispiel an der Interpretation des ersten, mit einem Punkt als
Dezimaltrenner geschriebenen Dezimalwertes, der hier als String
interpretiert wird und dem zweiten, mit Komma geschriebenen
Dezimalwert, der hier im deutschen Umfeld als double
erfasst wird.
Die Lokalisierung des Scanner-Objekts richtet sich in den Standard-Einstellungen nach der Laufzeitumgebung. Sie kann jedoch auch explizit gesetzt werden, wie es hier in der Zeile
scanner.useLocale(Locale.GERMANY);
demonstriert wird.
Das Leerzeichen als standardmäßig verwendeter
Elementtrenner kann durch die Methode useDelimiter()
nach Bedarf angepasst werden. Es wird an einem Beispiel
demonstriert, in dem hier ein hart codiertes String-Objekt
eingelesen wird.
String in = "eins#zwei#drei#vier"; Scanner scan = new Scanner(in).useDelimiter("#"); while(scan.hasNext()) { System.out.println(scan.next()); } scan.close();
Die Ausgabe liefert
eins zwei drei vier
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.