Scanner vs. BufferedReader

283

Soweit ich weiß, sind die beiden häufigsten Methoden der Lesezeichenbasierten Daten aus einer Datei in Java verwendet Scanneroder BufferedReader. Ich weiß auch, dass die BufferedReaderDateien effizient gelesen werden, indem ein Puffer verwendet wird, um physische Festplattenoperationen zu vermeiden.

Meine Fragen sind:

  • Funktioniert Scannerso gut wie BufferedReader?
  • Warum würden Sie wählen , Scannerüber BufferedReaderoder umgekehrt?
Mads Mobæk
quelle
1
Im Allgemeinen verwende ich Scanner auch zum Lesen von Standard-In ('Scanner in = neuer Scanner (System.in)' fühlt sich viel sauberer an). Ich bin mir nicht sicher, ob das tatsächlich weniger effizient ist, aber da das Lesen von std in blockiert, kann ich mir nicht vorstellen, dass die Effizienz des Scanners das Problem sein würde.
dimo414

Antworten:

201

Scannerwird zum Parsen von Token aus dem Inhalt des Streams verwendet, während BufferedReadernur der Stream gelesen wird und keine spezielle Analyse durchgeführt wird.

Tatsächlich können Sie a BufferedReaderan a scannerals Quelle für zu analysierende Zeichen übergeben.

Chandra Sekar
quelle
55
BufferedReader ist synchronisiert und Scanner nicht. Sie müssen also entscheiden.
Reuben
1
Ich weiß, dass dieses Thema alt ist, aber ich habe unter Betriebssystemen, die BufferedReader verwenden, gemischte Ergebnisse erzielt, als ich versucht habe, Inhalte aus den von Process bereitgestellten Streams zu verschlingen (dh die Ausgabe eines externen Befehls zu erfassen). Nachdem ich meinen Code geändert hatte, um stattdessen Scanner zu verwenden, wie in einer separaten Antwort angegeben , verhielten sich die Dinge konsistent und wie erwartet.
ewh
@Reuben Aber Scannerhängt letztendlich von etwas anderem für seine Eingabe ab, das durchaus synchronisiert werden kann.
Marquis von Lorne
189

In der derzeit neuesten JDK6-Version / Build (b27) hat der ScannerPuffer einen kleineren Puffer ( 1024 Zeichen ) als der BufferedReader( 8192 Zeichen ), aber er ist mehr als ausreichend.

Verwenden ScannerSie für die Auswahl die Option, wenn Sie die Datei analysieren möchten, und die Option , BufferedReaderwenn Sie die Datei Zeile für Zeile lesen möchten . Siehe auch den Einführungstext der oben verlinkten API-Dokumentationen.

  • Parsing = Interpretation der angegebenen Eingabe als Token (Teile). Es kann Ihnen bestimmte Teile direkt als int, string, decimal usw. zurückgeben. Siehe auch alle diese nextXxx()Methoden in der ScannerKlasse.
  • Lesen = dummes Streaming. Es gibt Ihnen immer wieder alle Charaktere zurück, die Sie wiederum manuell überprüfen müssen, wenn Sie etwas Nützliches finden oder komponieren möchten. Aber wenn Sie das sowieso nicht tun müssen, ist das Lesen ausreichend.
BalusC
quelle
1
Schön. Danke für den Puffertipp. Ich habe die ganze Zeit danach gesucht, da native Lesevorgänge extrem teuer sind.
Achow
7
@Asif: parsing = Interpretation der angegebenen Eingabe als Token (Teile). Sie können bestimmte Teile direkt als int, string, decimal usw. zurückgeben. Siehe auch alle nextXxx () -Methoden in der Scanner-Klasse. Lesen = dummes Streaming. Es gibt Ihnen immer wieder alle Charaktere zurück, die Sie wiederum manuell überprüfen müssen, wenn Sie etwas Nützliches finden oder komponieren möchten. Aber wenn Sie das sowieso nicht tun müssen, ist das Lesen ausreichend.
BalusC
@BalusC Ok, ich habe bereits verwendet, readInt();readFloat (); usw. Jetzt habe ich verstanden, was das Parsen bedeutet. und BalusC kannst du mir nur 10 Minuten im Chatraum wenig Zeit geben, ich möchte wenig nach gepuffert fragen, wie es funktioniert.
Asif Mushtaq
Was verpacke ich BufferedReaderin Scanners Konstruktor? Ist das eine gute Idee?
Vivek
1
ScannerDer Puffer wird nach Bedarf für den Mustervergleich erweitert. Wenn Sie also einen größeren Puffer wünschen, müssen Sie ihn nur aufrufen, z. B. findWithinHorizon("\\z", 8192)und danach wird ein Puffer mit einer Kapazität von 8192Zeichen verwendet (oder die gesamte Datei, wenn sie kleiner ist).
Holger
77

Siehe diesen Link , von dort wird folgendes zitiert:

Ein BufferedReader ist eine einfache Klasse, die effizient aus dem untergeordneten Stream lesen soll. Im Allgemeinen bewirkt jede Leseanforderung eines Readers wie eines FileReader, dass eine entsprechende Leseanforderung an den zugrunde liegenden Stream gesendet wird. Jeder Aufruf von read () oder readLine () kann dazu führen, dass Bytes aus der Datei gelesen, in Zeichen konvertiert und dann zurückgegeben werden, was sehr ineffizient sein kann. Die Effizienz wird erheblich verbessert, wenn ein Reader in einem BufferedReader verzogen wird.

BufferedReader ist synchronisiert, sodass Lesevorgänge auf einem BufferedReader sicher von mehreren Threads aus ausgeführt werden können.

In einen Scanner hingegen ist viel mehr Käse eingebaut. Es kann alles, was ein BufferedReader kann, und das bei gleicher Effizienz. Zusätzlich kann ein Scanner den zugrunde liegenden Stream jedoch mithilfe regulärer Ausdrücke auf primitive Typen und Zeichenfolgen analysieren. Es kann auch den zugrunde liegenden Stream mit dem Trennzeichen Ihrer Wahl tokenisieren. Es kann auch eine Vorwärtsabtastung des zugrunde liegenden Streams ohne Berücksichtigung des Trennzeichens durchführen!

Ein Scanner ist jedoch nicht threadsicher, sondern muss extern synchronisiert werden.

Die Wahl eines BufferedReader oder eines Scanners hängt vom Code ab, den Sie schreiben. Wenn Sie einen einfachen Protokollleser schreiben, ist ein gepufferter Leser ausreichend. Wenn Sie jedoch einen XML-Parser schreiben, ist Scanner die natürlichere Wahl.

Selbst beim Lesen der Eingabe ist ein BufferedReader gut genug, wenn Sie Benutzereingaben zeilenweise akzeptieren und einfach zu einer Datei hinzufügen möchten. Wenn Sie andererseits Benutzereingaben als Befehl mit mehreren Optionen akzeptieren und dann beabsichtigen, basierend auf dem angegebenen Befehl und den angegebenen Optionen unterschiedliche Vorgänge auszuführen, ist ein Scanner besser geeignet.

Jomoos
quelle
"In einen Scanner hingegen ist viel mehr Käse eingebaut. Er kann alles, was ein BufferedReader kann, und das bei gleicher Effizienz." Stimmen Sie nicht zu, BufferedReader ist im Vergleich zu Scanner etwas schneller, da Scanner Eingabedaten analysiert und BufferedReader einfach die Zeichenfolge liest.
Pratik
40
  1. BufferedReaderhat deutlich größeren Pufferspeicher als Scanner. Verwenden BufferedReaderSie diese Option, wenn Sie lange Zeichenfolgen aus einem Stream Scannerabrufen möchten , und verwenden Sie diese Option , wenn Sie einen bestimmten Tokentyp aus einem Stream analysieren möchten.

  2. ScannerSie können Tokenize mithilfe eines benutzerdefinierten Trennzeichens verwenden und den Stream in primitive Datentypen analysieren, während Sie BufferedReadernur String lesen und speichern können.

  3. BufferedReaderist synchron, während Scannernicht. Verwenden BufferedReaderSie diese Option, wenn Sie mit mehreren Threads arbeiten.

  4. Scannerversteckt die IOException, während BufferedReadersie sofort ausgelöst wird .

Sujith PS
quelle
18

Ich schlage vor, BufferedReaderzum Lesen von Text zu verwenden. Scannerversteckt sich, IOExceptionwährend BufferedReaderes sofort wirft.

Evgeniy
quelle
12

Der Unterschied zwischen BufferedReader und Scanner ist folgender:

  1. BufferedReader ist synchronisiert, aber der Scanner ist nicht synchronisiert .
  2. BufferedReader ist threadsicher, aber Scanner ist nicht threadsicher .
  3. BufferedReader hat einen größeren Pufferspeicher, aber Scanner hat einen kleineren Pufferspeicher .
  4. BufferedReader ist schneller, aber der Scanner ist langsamer in der Ausführung .
  5. Code zum Lesen einer Zeile von der Konsole:

    BufferedReader :

     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br= new BufferedReader(isr);
     String st= br.readLine();

    Scanner :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();
Raman Gupta
quelle
8

Im Folgenden sind die Unterschiede zwischen BufferedReader und Scanner aufgeführt

  1. BufferedReader liest nur Daten, aber der Scanner analysiert auch Daten.
  2. Sie können String nur mit BufferedReader lesen, aber Sie können int, long oder float mit Scanner lesen.
  3. BufferedReader ist älter als Scanner und existiert ab JDK 1.1, während Scanner in JDK 5 hinzugefügt wurde.
  4. Die Puffergröße von BufferedReader ist groß (8 KB) im Vergleich zu 1 KB Scanner.
  5. BufferedReader eignet sich besser zum Lesen von Dateien mit langen Zeichenfolgen, während Scanner besser zum Lesen kleiner Benutzereingaben an der Eingabeaufforderung geeignet ist.
  6. BufferedReader ist synchronisiert, Scanner jedoch nicht. Dies bedeutet, dass Sie den Scanner nicht für mehrere Threads freigeben können.
  7. BufferedReader ist schneller als Scanner, da keine Zeit für das Parsen aufgewendet wird
  8. BufferedReader ist im Vergleich zu Scanner etwas schneller
  9. BufferedReader stammt aus dem Paket java.io und Scanner stammt aus dem Paket java.util, basierend auf den Punkten, die wir auswählen können.

Vielen Dank

dhS
quelle
6

Die Hauptunterschiede:

  1. Scanner

  • Ein einfacher Textscanner, der primitive Typen und Zeichenfolgen mithilfe regulärer Ausdrücke analysieren kann.
  • Ein Scanner unterteilt seine Eingabe mithilfe eines Begrenzungsmusters in Token, das standardmäßig mit Leerzeichen übereinstimmt. Die resultierenden Token können dann unter Verwendung der verschiedenen nächsten Methoden in Werte verschiedener Typen umgewandelt werden.

Beispiel

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

druckt die folgende Ausgabe:

 1
 2
 red
 blue 

Dieselbe Ausgabe kann mit diesem Code generiert werden, der einen regulären Ausdruck verwendet, um alle vier Token gleichzeitig zu analysieren:

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i=1; i<=result.groupCount(); i++)
     System.out.println(result.group(i));
 s.close(); `


  1. BufferedReader:

    • Liest Text aus einem Zeicheneingabestream und puffert Zeichen, um das effiziente Lesen von Zeichen, Arrays und Zeilen zu ermöglichen.

    • Die Puffergröße kann angegeben oder die Standardgröße verwendet werden. Die Standardeinstellung ist für die meisten Zwecke groß genug.

Im Allgemeinen bewirkt jede Leseanforderung eines Lesers, dass eine entsprechende Leseanforderung des zugrunde liegenden Zeichens oder Bytestroms gestellt wird. Es ist daher ratsam, einen BufferedReader um jeden Reader zu wickeln, dessen read () -Operationen kostspielig sein können, z. B. FileReaders und InputStreamReaders. Zum Beispiel,

BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));

puffert die Eingabe aus der angegebenen Datei. Ohne Pufferung kann jeder Aufruf von read () oder readLine () dazu führen, dass Bytes aus der Datei gelesen, in Zeichen konvertiert und dann zurückgegeben werden, was sehr ineffizient sein kann. Programme, die DataInputStreams für die Texteingabe verwenden, können lokalisiert werden, indem jeder DataInputStream durch einen geeigneten BufferedReader ersetzt wird.

Quelle: Link

Shiva Nandam Sirmarigari
quelle
3

Es gibt verschiedene Möglichkeiten, Eingaben in Java vorzunehmen:

1) BufferedReader 2) Scanner 3) Befehlszeilenargumente

BufferedReader Liest Text aus einem Zeicheneingabestream und puffert Zeichen, um das effiziente Lesen von Zeichen, Arrays und Zeilen zu ermöglichen.

Wobei Scanner ein einfacher Textscanner ist, der primitive Typen und Zeichenfolgen mithilfe regulärer Ausdrücke analysieren kann.

Wenn Sie einen einfachen Protokollleser schreiben, ist ein gepufferter Leser ausreichend. Wenn Sie einen XML-Parser schreiben, ist Scanner die natürlichere Wahl.

Weitere Informationen finden Sie unter:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69

Manisha Mulchandani
quelle
1

Die folgende Antwort stammt aus Reading from Console: JAVA Scanner vs BufferedReader

Wenn Sie eine Eingabe von der Konsole lesen, gibt es zwei Möglichkeiten, um dies zu erreichen. Erstes Verwenden Scanner, ein anderes Verwenden BufferedReader. Beide haben unterschiedliche Eigenschaften. Es bedeutet Unterschiede, wie man es benutzt.

Der Scanner behandelte die angegebene Eingabe als Token. BufferedReader liest nur Zeile für Zeile und gibt die Eingabe als Zeichenfolge ein. Scanner selbst bieten Parsing-Funktionen wie nextInt (), nextFloat ().

Aber was sind andere Unterschiede zwischen?

  • Der Scanner behandelte die angegebene Eingabe als Token. BufferedReader als Streamline / String
  • Der Scanner hat die Eingabe mithilfe von Regex mit einem Token versehen. Bei Verwendung von BufferedReader muss zusätzlicher Code geschrieben werden
  • BufferedReader schneller als Scanner * Punkt-Nr. 2
  • Scanner ist nicht synchronisiert, BufferedReader synchronisiert

Scanner kommen mit seit JDK Version 1.5 höher.

Wann sollte Scanner oder Buffered Reader verwendet werden?

Schauen Sie sich die Hauptunterschiede zwischen beiden an, einer mit Token, andere mit Streamline. Wenn Sie Analysefunktionen benötigen, verwenden Sie stattdessen den Scanner. Aber ich fühle mich mit BufferedReader wohler. Wenn Sie aus einer Datei lesen müssen, verwenden Sie BufferedReader, da beim Lesen einer Datei Puffer verwendet wird. Oder Sie können BufferedReader als Eingabe für den Scanner verwenden.

KNU
quelle
0
  1. BufferedReader bietet wahrscheinlich eine bessere Leistung (da der Scanner auf InputStreamReader basiert, siehe Quellen). ups, zum lesen aus dateien wird nio verwendet. Als ich die nio-Leistung gegen die BufferedReader-Leistung für große Dateien getestet habe, zeigt nio eine etwas bessere Leistung.
  2. Versuchen Sie zum Lesen aus der Datei Apache Commons IO.
römisch
quelle
0

Ich bevorzuge es, Scannerweil es keine geprüften Ausnahmen auslöst und daher die Verwendung zu einem optimierten Code führt.

Das ist mein Design
quelle