BufferedReader vs Console vs Scanner in Java

1. Übersicht

In diesem Artikel werden die Unterschiede zwischen den Klassen BufferedReader , Console und Scanner in Java erläutert .

Um sich eingehend mit jedem Thema zu befassen, empfehlen wir Ihnen, einen Blick auf unsere einzelnen Artikel zu Java Scanner, Konsolen-E / A in Java und BufferedReader zu werfen.

2. Benutzereingabe

Angesichts des zugrunde liegenden Streams, der an die Konstruktoren übergeben wird, können sowohl die BufferedReader- als auch die Scanner- Klasse einen größeren Bereich von Benutzereingaben verarbeiten , z. B. eine Zeichenfolge, eine Datei, eine Systemkonsole (die normalerweise mit der Tastatur verbunden ist) und einen Socket.

Andererseits ist die Konsolenklasse so konzipiert, dass sie nur auf die zeichenbasierte Systemkonsole zugreift, die der aktuellen virtuellen Java-Maschine zugeordnet ist.

Werfen wir einen Blick auf die BufferedReader- Konstruktoren, die unterschiedliche Eingaben akzeptieren:

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())); 

Die Scannerklasse könnte in ähnlicher Weise auch unterschiedliche Eingaben in ihren Konstruktoren akzeptieren:

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());

Die Console- Klasse ist nur über den Methodenaufruf verfügbar:

Console console = System.console();

Beachten Sie bitte, dass bei Verwendung der Console- Klasse die JVM-zugeordnete Systemkonsole nicht verfügbar ist, wenn wir den Code in einer IDE wie Eclipse oder IntelliJ IDEA ausführen.

3. Benutzerausgabe

Im Gegensatz zu den Klassen BufferedReader und Scanner , die nichts in den Ausgabestream schreiben, bietet die Console- Klasse einige praktische Methoden wie readPassword (String fmt, Object… args), readLine (String fmt, Object… args) und printf ( Zeichenfolgenformat, Object… args) , um die Eingabeaufforderung in den Ausgabestream der Systemkonsole zu schreiben :

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

Wenn wir also ein Programm für die Interaktion mit der Systemkonsole schreiben, vereinfacht die Console- Klasse den Code, indem unnötige System.out.println entfernt werden .

4. Eingabe analysieren

Die Scannerklasse kann primitive Typen und Zeichenfolgen mithilfe regulärer Ausdrücke analysieren .

Die Eingabe wird mithilfe eines benutzerdefinierten Trennzeichens in Token aufgeteilt, das standardmäßig mit Leerzeichen übereinstimmt:

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();

Die Klassen BufferredReader und Console lesen den Eingabestream einfach so, wie er ist.

5. Sichere Daten lesen

Die Console- Klasse verfügt über die Methoden readPassword () und readPassword (String fmt , Object… args) , um die sicheren Daten mit deaktiviertem Echo zu lesen, sodass Benutzer nicht sehen, was sie eingeben:

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

BufferedReader und Scanner können dies nicht.

6. Thread sicher

Die Lesemethoden in BufferedReader und die Lese- und Schreibmethoden in Console sind alle synchronisiert , die in der Scannerklasse jedoch nicht. Wenn wir die Benutzereingaben in einem Multithread-Programm lesen, ist entweder BufferedReader oder Console die bessere Option.

7. Puffergröße

Die Puffergröße ist 8 KB in BufferedReader im Vergleich zu 1 KB in Scanner - Klasse .

Darüber hinaus können wir bei Bedarf die Puffergröße im Konstruktor der BufferedReader- Klasse angeben . Dies hilft beim Lesen der langen Zeichenfolgen aus Benutzereingaben. Die Konsolenklasse hat keinen Puffer beim Lesen von der Systemkonsole , aber einen gepufferten Ausgabestream zum Schreiben in die Systemkonsole.

8. Verschiedenes

Es gibt einige Unterschiede, die nicht die Hauptfaktoren sind, die wir bei der Auswahl der geeigneten Klasse für verschiedene Situationen berücksichtigen.

8.1. Schließen des Eingabestreams

Sobald wir die Instanz von BufferedReader oder Scanner erstellt haben , müssen wir daran denken, sie zu schließen, um einen Speicherverlust zu vermeiden . Dies ist jedoch bei der Console- Klasse nicht der Fall. Wir müssen die Systemkonsole nach der Verwendung nicht schließen.

8.2. Ausnahmebehandlung

Während Scanner und Konsole den ungeprüften Ausnahmeansatz verwenden, lösen Methoden in BufferedReader geprüfte Ausnahmen aus, wodurch wir gezwungen sind, eine Try-Catch-Syntax für Boilerplates zu schreiben, um die Ausnahmen zu behandeln.

9. Fazit

Nachdem wir nun die Unterschiede zwischen diesen Klassen angegeben haben, wollen wir einige Faustregeln festlegen, welche für verschiedene Situationen am besten geeignet sind :

  • Use BufferedReader if we need to read long strings from a file, as it has better performance than Scanner
  • Consider Console if we're reading secure data from the system console and want to hide what is being typed
  • Use Scanner if we need to parse the input stream with a custom regular expression
  • Scanner would be preferred when we interact with the system console, as it offers fine-grained methods to read and parse the input stream. In addition, the performance drawback is not a big problem, as in most cases, the nextXXX methods are blocking and wait for manual input
  • Berücksichtigen Sie in einem thread-sicheren Kontext BufferedReader, es sei denn, wir müssen Funktionen verwenden, die für die Console- Klasse spezifisch sind