BufferedReader vs Console vs Scanner in Java

1. Panoramica

In questo articolo, esamineremo le differenze tra le classi BufferedReader , Console e Scanner in Java .

Per approfondire ogni argomento, suggeriamo di dare un'occhiata ai nostri singoli articoli su Java Scanner, Console I / O in Java e BufferedReader.

2. Input dell'utente

Dato il flusso sottostante passato ai costruttori, entrambe le classi BufferedReader e Scanner sono in grado di gestire una gamma più ampia di input dell'utente , come una stringa, un file, una console di sistema (che è tipicamente connessa alla tastiera) e un socket.

D'altra parte, la classe Console è progettata per accedere solo alla console di sistema basata sui caratteri, se presente, associata alla Java virtual machine corrente.

Diamo uno sguardo ai costruttori di BufferedReader , che accettano diversi input:

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

Il dispositivo d'esplorazione di classe poteva accettare simile ingressi differenti nei suoi costruttori, nonché:

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

La classe Console è disponibile solo tramite la chiamata al metodo:

Console console = System.console();

Tieni presente che quando usiamo la classe Console , la console di sistema associata a JVM non è disponibile se eseguiamo il codice all'interno di un IDE come Eclipse o IntelliJ IDEA.

3. Uscita utente

A differenza delle classi BufferedReader e Scanner , che non scrivono nulla nel flusso di output, la classe Console offre alcuni metodi convenienti come readPassword (String fmt, Object… args), readLine (String fmt, Object… args) e printf ( Formato stringa, Oggetto ... argomenti) , per scrivere il prompt nel flusso di output della console di sistema :

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

Quindi, quando scriviamo un programma per interagire con la console di sistema, la classe Console semplificherà il codice rimuovendo System.out.println non necessario .

4. Analisi dell'input

La classe Scanner può analizzare tipi e stringhe primitive utilizzando espressioni regolari .

Divide il suo input in token utilizzando un modello delimitatore personalizzato, che per impostazione predefinita corrisponde agli spazi bianchi:

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

Le classi BufferredReader e Console leggono semplicemente il flusso di input così com'è.

5. Lettura di dati protetti

La classe Console ha i metodi readPassword () e readPassword (String fmt , Object ... args) per leggere i dati protetti con l'eco disabilitato in modo che gli utenti non vedano cosa stanno digitando:

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

BufferedReader e Scanner non sono in grado di farlo.

6. Discussione sicura

I metodi di lettura in BufferedReader e i metodi di lettura e scrittura in Console sono tutti sincronizzati , mentre quelli nella classe Scanner non lo sono. Se leggiamo l'input dell'utente in un programma multi-thread, BufferedReader o Console sarà un'opzione migliore.

7. Dimensione del buffer

La dimensione del buffer è 8 KB in BufferedReader rispetto a 1 KB nella classe Scanner .

Inoltre, possiamo specificare la dimensione del buffer nel costruttore della classe BufferedReader , se necessario. Ciò aiuterà durante la lettura delle stringhe lunghe dall'input dell'utente. La classe console non ha buffer durante la lettura dalla console di sistema , ma ha un flusso di output bufferizzato da scrivere nella console di sistema.

8. Varie

Ci sono alcune differenze che non sono i fattori principali da considerare quando si sceglie la classe appropriata da utilizzare in varie situazioni.

8.1. Chiusura del flusso di input

Una volta creata l'istanza di BufferedReader o Scanner , dobbiamo ricordarci di chiuderla per evitare una perdita di memoria . Ma questo non accade con la classe Console : non è necessario chiudere la console di sistema dopo l'uso.

8.2. La gestione delle eccezioni

Mentre Scanner e Console adottano l'approccio delle eccezioni non controllate, i metodi in BufferedReader generano eccezioni controllate, il che ci obbliga a scrivere la sintassi try-catch boilerplate per gestire le eccezioni.

9. Conclusione

Ora che abbiamo indicato le differenze tra queste classi, veniamo a creare alcune regole pratiche su quale (s) è più adatta per affrontare situazioni diverse :

  • Usa BufferedReader se abbiamo bisogno di leggere stringhe lunghe da un file, poiché ha prestazioni migliori di Scanner
  • Considera Console se stiamo leggendo dati protetti dalla console di sistema e vogliamo nascondere ciò che viene digitato
  • Usa Scanner se abbiamo bisogno di analizzare il flusso di input con un'espressione regolare personalizzata
  • Lo scanner sarebbe preferito quando interagiamo con la console di sistema, poiché offre metodi granulari per leggere e analizzare il flusso di input. Inoltre, lo svantaggio delle prestazioni non è un grosso problema, poiché nella maggior parte dei casi i metodi nextXXX si bloccano e attendono l'input manuale
  • In un contesto thread-safe, si consideri BufferedReader a meno che non sia necessario utilizzare funzionalità specifiche per la classe Console