Scanner vs. BufferedReader


284

Per quanto ne so, i due metodi più comuni per leggere i dati basati sui caratteri da un file in Java stanno utilizzando Scannero BufferedReader. So anche che BufferedReaderlegge i file in modo efficiente utilizzando un buffer per evitare operazioni fisiche del disco.

Le mie domande sono:

  • Si Scanneresibisce così come BufferedReader?
  • Perché dovresti scegliere Scanneroltre BufferedReadero viceversa?

1
In genere utilizzo anche Scanner per leggere dallo standard in ("Scanner in = new Scanner (System.in)" è molto più pulito). Non sono sicuro che sia effettivamente meno efficiente, ma poiché la lettura da std in sta bloccando, non posso immaginare che l'efficienza dello scanner sarebbe il problema.
dimo414,

Risposte:


201

Scannerviene utilizzato per l'analisi dei token dal contenuto dello stream mentre BufferedReaderlegge lo stream e non esegue alcuna analisi speciale.

In effetti puoi passare da BufferedReadera a scannercome fonte di caratteri da analizzare.


55
BufferedReader è sincronizzato e Scanner no, quindi spetta a te decidere.
Reuben,

1
So che questo argomento è vecchio, ma ho avuto risultati contrastanti tra i sistemi operativi usando BufferedReader quando ho cercato di snellire il contenuto dagli stream forniti da Process (ovvero catturare l'output di un comando esterno). Una volta modificato il mio codice per utilizzare Scanner invece, come indicato in una risposta separata , le cose hanno iniziato a comportarsi in modo coerente e come previsto.
ewh

@Reuben Ma alla Scannerfine dipende da qualcos'altro per il suo input, che potrebbe essere sincronizzato.
Marchese di Lorne,

189

Nell'ultima release / build JDK6 (b27), Scannerha un buffer più piccolo ( 1024 caratteri ) rispetto ai BufferedReader( 8192 caratteri ), ma è più che sufficiente.

Per quanto riguarda la scelta, utilizzare Scannerse si desidera analizzare il file, utilizzare BufferedReaderse si desidera leggere il file riga per riga. Vedi anche il testo introduttivo delle loro precedenti documentazioni API.

  • Analisi = interpretazione dell'input dato come token (parti). È in grado di restituirti parti specifiche direttamente come int, stringa, decimale, ecc. Vedi anche tutti quei nextXxx()metodi in Scannerclasse.
  • Lettura = streaming muto. Ti restituisce tutti i personaggi, che a sua volta devi ispezionare manualmente se desideri abbinare o comporre qualcosa di utile. Ma se non è necessario farlo comunque, la lettura è sufficiente.

1
Ben fatto. Grazie per il suggerimento sul buffer. Lo cercavo da sempre perché le letture native sono estremamente costose.
Achow,

7
@Asif: parsing = interpretando l'input dato come token (parti). È in grado di restituirti parti specifiche direttamente come int, stringa, decimale, ecc. Vedi anche tutti quei metodi nextXxx () nella classe Scanner. Lettura = streaming muto. Ti restituisce tutti i personaggi, che a sua volta devi ispezionare manualmente se desideri abbinare o comporre qualcosa di utile. Ma se non è necessario farlo comunque, la lettura è sufficiente.
BalusC,

@BalusC Ok ho già usato, readInt();readFloat (); ecc. Ora ho capito qual è il mezzo di analisi. e BalusC puoi darmi poco tempo a soli 10 minuti in chat room, voglio chiedere poco su buffered, come funziona.
Asif Mushtaq,

Cosa avvolgo BufferedReadernel costruttore dello scanner? E 'questa una buona idea?
vivek,

1
ScannerIl buffer verrà espanso secondo necessità per la corrispondenza del modello. Quindi se vuoi un buffer più grande, devi solo invocare, ad esempio findWithinHorizon("\\z", 8192), su di esso e successivamente, utilizzerà un buffer con una capacità di 8192caratteri (o l'intero file se è più piccolo di quello).
Holger

77

Vedi questo link , il seguente è citato da lì:

Un BufferedReader è una classe semplice pensata per leggere in modo efficiente dal flusso sottostante. In genere, ogni richiesta di lettura fatta da un Reader come un FileReader fa in modo che una richiesta di lettura corrispondente venga inviata al flusso sottostante. Ogni invocazione di read () o readLine () potrebbe causare la lettura dei byte dal file, la conversione in caratteri e la successiva restituzione, il che può essere molto inefficiente. L'efficienza è notevolmente migliorata se un Reader è deformato in un BufferedReader.

BufferedReader è sincronizzato, quindi le operazioni di lettura su BufferedReader possono essere eseguite in sicurezza da più thread.

Uno scanner d'altra parte ha molto più formaggio incorporato; può fare tutto ciò che può fare un BufferedReader e allo stesso livello di efficienza. Tuttavia, inoltre, uno scanner può analizzare il flusso sottostante per tipi e stringhe primitivi utilizzando espressioni regolari. Può anche tokenizzare il flusso sottostante con il delimitatore di tua scelta. Può anche eseguire la scansione in avanti del flusso sottostante ignorando il delimitatore!

Uno scanner tuttavia non è sicuro per i thread, ma deve essere sincronizzato esternamente.

La scelta di utilizzare un BufferedReader o uno scanner dipende dal codice che si sta scrivendo, se si sta scrivendo un semplice lettore di log Il lettore con buffer è adeguato. Tuttavia, se stai scrivendo un parser XML, Scanner è la scelta più naturale.

Anche durante la lettura dell'input, se si desidera accettare l'input dell'utente riga per riga e dire semplicemente aggiungerlo a un file, un BufferedReader è abbastanza buono. D'altra parte, se si desidera accettare l'input dell'utente come comando con più opzioni e quindi si intende eseguire diverse operazioni in base al comando e alle opzioni specificate, uno scanner si adatterà meglio.


"D'altro canto, uno scanner ha molto più formaggio incorporato; può fare tutto ciò che può fare un BufferedReader e allo stesso livello di efficienza." Non sono d'accordo, BufferedReader è un po 'più veloce rispetto a Scanner perché Scanner analizza i dati di input e BufferedReader legge semplicemente la sequenza di caratteri.
Pratik,

40
  1. BufferedReaderha una memoria buffer significativamente maggiore rispetto allo scanner. Utilizzare BufferedReaderse si desidera ottenere stringhe lunghe da uno stream e utilizzare Scannerse si desidera analizzare un tipo specifico di token da uno stream.

  2. Scannerpuò usare il tokenize usando il delimitatore personalizzato e analizzare il flusso in tipi di dati primitivi, mentre BufferedReaderpuò solo leggere e archiviare String.

  3. BufferedReaderè sincrono mentre Scannernon lo è. Utilizzare BufferedReaderse si lavora con più thread.

  4. Scannernasconde IOException mentre la BufferedReaderlancia immediatamente.


18

Suggerisco di usare BufferedReaderper leggere il testo. Scannersi nasconde IOExceptionmentre lo BufferedReaderlancia immediatamente.


12

Le differenze tra BufferedReader e Scanner sono le seguenti:

  1. BufferedReader è sincronizzato ma Scanner non è sincronizzato .
  2. BufferedReader è thread-safe ma Scanner non è thread-safe .
  3. BufferedReader ha una memoria buffer più grande ma Scanner ha una memoria buffer più piccola .
  4. BufferedReader è più veloce ma Scanner è più lento nell'esecuzione .
  5. Codice per leggere una riga dalla console:

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

8

Di seguito sono riportate le differenze tra BufferedReader e Scanner

  1. BufferedReader legge solo i dati ma lo scanner analizza anche i dati.
  2. puoi leggere solo String usando BufferedReader, ma puoi leggere int, long o float usando Scanner.
  3. BufferedReader è più vecchio di Scanner, esiste da jdk 1.1 mentre Scanner è stato aggiunto alla versione JDK 5.
  4. La dimensione del buffer di BufferedReader è grande (8 KB) rispetto a 1 KB dello scanner.
  5. BufferedReader è più adatto per la lettura di file con String lunga mentre Scanner è più adatto per la lettura di input di piccoli utenti dal prompt dei comandi.
  6. BufferedReader è sincronizzato ma Scanner no, il che significa che non è possibile condividere Scanner tra più thread.
  7. BufferedReader è più veloce di Scanner perché non impiega tempo ad analizzare
  8. BufferedReader è un po 'più veloce rispetto allo scanner
  9. BufferedReader proviene dal pacchetto java.io e Scanner viene dal pacchetto java.util sulla base dei punti che possiamo selezionare la nostra scelta.

Grazie


6

Le principali differenze:

  1. Scanner

  • Un semplice scanner di testo in grado di analizzare tipi e stringhe primitivi usando espressioni regolari.
  • Uno scanner suddivide il proprio input in token utilizzando un modello di delimitatore, che per impostazione predefinita corrisponde agli spazi bianchi. I token risultanti possono quindi essere convertiti in valori di diversi tipi utilizzando i vari metodi successivi.

Esempio

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

stampa il seguente output:

 1
 2
 red
 blue 

Lo stesso output può essere generato con questo codice, che utilizza un'espressione regolare per analizzare tutti e quattro i token contemporaneamente:

 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:

    • Legge il testo da un flusso di input di caratteri, memorizza i caratteri in modo da fornire una lettura efficiente di caratteri, matrici e linee.

    • È possibile specificare la dimensione del buffer oppure utilizzare la dimensione predefinita. L'impostazione predefinita è abbastanza grande per la maggior parte degli scopi.

In generale, ogni richiesta di lettura fatta di un Reader fa sì che venga fatta una richiesta di lettura corrispondente del carattere o flusso di byte sottostante. È quindi consigliabile avvolgere un BufferedReader attorno a qualsiasi Reader le cui operazioni read () possano essere costose, come FileReaders e InputStreamReaders. Per esempio,

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

bufferizzerà l'input dal file specificato. Senza buffering, ogni invocazione di read () o readLine () potrebbe causare la lettura dei byte dal file, la conversione in caratteri e la successiva restituzione, che può essere molto inefficiente. I programmi che utilizzano DataInputStreams per l'input testuale possono essere localizzati sostituendo ciascun DataInputStream con un BufferedReader appropriato.

Fonte: Link


3

Esistono diversi modi per ricevere input in java come:

1) BufferedReader 2) Scanner 3) Argomenti della riga di comando

BufferedReader Legge il testo da un flusso di input di caratteri, memorizza i caratteri nel buffer in modo da fornire una lettura efficiente di caratteri, matrici e linee.

Dove Scanner è un semplice scanner di testo in grado di analizzare tipi e stringhe primitivi utilizzando espressioni regolari.

se stai scrivendo un semplice lettore di log Il lettore con buffer è adeguato. se stai scrivendo un parser XML Scanner è la scelta più naturale.

Per ulteriori informazioni, consultare:

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


1

La risposta che segue è tratta dalla lettura dalla console: JAVA Scanner vs BufferedReader

Quando leggi un input dalla console, esistono due opzioni per raggiungere questo obiettivo. Primo utilizzo Scanner, un altro utilizzo BufferedReader. Entrambi hanno caratteristiche diverse. Significa differenze su come usarlo.

Lo scanner ha trattato l'input dato come token. BufferedReader ha appena letto riga per riga l'input fornito come stringa. Scanner stesso fornisce funzionalità di analisi proprio come nextInt (), nextFloat ().

Ma quali sono le altre differenze?

  • Lo scanner ha trattato l'input dato come token. BufferedReader come stream line / String
  • Scanner tokenizzato input dato usando regex. Utilizzando BufferedReader è necessario scrivere un codice aggiuntivo
  • BufferedReader più veloce dello scanner * punto n. 2
  • Lo scanner non è sincronizzato, BufferedReader sincronizzato

Scanner fornito dalla versione JDK 1.5 in poi.

Quando utilizzare Scanner o Reader con buffer?

Guarda le principali differenze tra i due, uno usando tokenized, altri usando stream line. Quando sono necessarie funzionalità di analisi, utilizzare invece Scanner. Ma sono più a mio agio con BufferedReader. Quando è necessario leggere da un file, utilizzare BufferedReader, poiché utilizza il buffer quando si legge un file. Oppure puoi usare BufferedReader come input per Scanner.


0
  1. BufferedReader ti darà probabilmente prestazioni migliori (perché lo scanner si basa su InputStreamReader, guarda le fonti). up, per leggere da file usa nio. Quando ho testato le prestazioni di nio rispetto alle prestazioni di BufferedReader per file di grandi dimensioni, nio mostra prestazioni leggermente migliori.
  2. Per leggere dal file provare Apache Commons IO.

0

Preferisco Scannerperché non genera eccezioni verificate e quindi i suoi risultati di utilizzo in un codice più snello.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.