Leggere l'Input dalla Console in Java
- Utilizzare
BufferedReader
eInputStreamReader
per leggere l'input da console in modo efficiente. - A partire da JDK 17, è consigliato specificare il charset quando si crea un
InputStreamReader
collegato aSystem.in
. - Per leggere un singolo carattere, utilizzare il metodo
read()
diBufferedReader
. - Per leggere una riga di testo, utilizzare il metodo
readLine()
diBufferedReader
. - Gestire le eccezioni I/O in modo appropriato, specialmente in applicazioni più complesse.
Lettura dell'Input da Console
Nei primi tempi di Java, l'unico modo per effettuare l'input da console era utilizzare uno stream di byte.
Oggi, utilizzare uno stream di byte per leggere l'input da console è ancora spesso accettabile, come quando viene utilizzato nei programmi di esempio. Tuttavia, per le applicazioni commerciali, il metodo preferito per leggere l'input da console è utilizzare uno stream a caratteri. Questo rende il programma più facile da internazionalizzare e mantenere.
In Java, l'input da console si ottiene (direttamente o indirettamente) leggendo da System.in
. Un modo per ottenere uno stream a caratteri che è collegato alla console è incapsulare System.in
in un BufferedReader
. La classe BufferedReader
supporta uno stream di input bufferizzato. Un costruttore comunemente utilizzato è mostrato qui:
BufferedReader(Reader input)
Qui, input
è lo stream che è collegato all'istanza di BufferedReader
che viene creata. Reader
è una classe astratta. Una delle sue sottoclassi concrete è InputStreamReader
, che converte i byte in caratteri.
A partire da JDK 17, il modo preciso in cui si ottiene un InputStreamReader
collegato a System.in
è cambiato.
In passato, era comune utilizzare il seguente costruttore InputStreamReader
per questo scopo:
InputStreamReader(InputStream stream)
Poiché System.in
si riferisce a un oggetto di tipo InputStream
, può essere utilizzato per stream
. Quindi, in passato, la seguente riga di codice mostra un approccio comunemente utilizzato per creare un BufferedReader
collegato alla tastiera:
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
Dopo l'esecuzione di questa istruzione, br
è uno stream a caratteri che è collegato alla console attraverso System.in
.
Tuttavia, a partire da JDK 17, ora è raccomandato specificare esplicitamente il charset associato alla console quando si crea l'InputStreamReader
. Un charset definisce il modo in cui i byte vengono mappati ai caratteri. Normalmente, quando un charset non è specificato, viene utilizzato il charset predefinito della JVM. Tuttavia, nel caso della console, il charset utilizzato per l'input da console può differire da questo charset predefinito. Quindi, ora è raccomandato che questa forma del costruttore di InputStreamReader
venga utilizzata:
InputStreamReader(InputStream stream, Charset charset)
Per charset
, si può utilizzare il charset associato alla console. Questo charset è restituito da charset()
, che è un nuovo metodo aggiunto da JDK 17 alla classe Console
. Si ottiene un oggetto Console
chiamando System.console()
. Restituisce un riferimento alla console, o null
se non è presente alcuna console. Pertanto, oggi la seguente sequenza mostra un modo per incapsulare System.in
in un BufferedReader
:
// Ottiene la Console
Console con = System.console();
if (con == null) {
// Il Sistema non ha una console
return;
}
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in, con.charset()));
Naturalmente, nei casi in cui si sa che una console sarà presente, la sequenza può essere accorciata a:
BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in,
System.console().charset()));
Un altro punto da tener presente: È anche possibile ottenere un Reader
che è già associato alla console utilizzando il metodo reader()
definito da Console
. Tuttavia, utilizzeremo l'approccio InputStreamReader
come appena descritto perché dimostra esplicitamente il modo in cui i byte stream e i character stream possono interagire.
Lettura di Caratteri
Per leggere un carattere da un BufferedReader
, utilizziamo read()
.
La versione di read()
che utilizzeremo è
int read() throws IOException
Ogni volta che viene chiamato, read()
legge un carattere dal flusso di input e lo restituisce come valore intero. Restituisce –1
quando viene fatto un tentativo di lettura alla fine del flusso. Come possiamo vedere, può lanciare un IOException
.
Il seguente programma dimostra read()
leggendo caratteri dalla console finché l'utente non digita una "q
". Notiamo che qualsiasi eccezione I/O che potrebbe essere generata viene semplicemente lanciata fuori da main()
. Tale approccio è comune quando si legge dalla console in semplici programmi di esempio come quelli mostrati in queste lezioni, ma in applicazioni più sofisticate, possiamo gestire le eccezioni esplicitamente.
// Utilizziamo un BufferedReader per leggere caratteri dalla console.
import java.io.*;
class BRLeggi {
public static void main(String[] args) throws IOException {
char c;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, System.console().charset()));
System.out.println("Inserisci caratteri, 'q' per uscire.");
// leggiamo caratteri
do {
c = (char) br.read();
System.out.println(c);
} while (c != 'q');
}
}
Ecco un esempio di esecuzione:
Inserisci caratteri, 'q' per uscire.
ciao
c
i
a
o
Come si va?
C
o
m
e
s
i
v
a
?
q
q
Questo output potrebbe apparire un po' diverso da quello che ci aspettavamo perché System.in
è bufferizzato per linea, per default. Questo significa che nessun input viene effettivamente passato al programma finché non premiamo invio. Come possiamo immaginare, questo non rende read()
particolarmente utile per l'input interattivo dalla console.
Leggere Stringhe
Per leggere una stringa dalla tastiera, utilizziamo la versione di readLine()
che è un membro della classe BufferedReader
. La sua forma generale è mostrata qui:
String readLine() throws IOException
Come possiamo vedere, restituisce un oggetto String
.
Il seguente programma dimostra BufferedReader
e il metodo readLine()
; il programma legge e visualizza righe di testo finché non inseriamo la parola "stop
":
// Legge una stringa dalla console usando un BufferedReader.
import java.io.*;
class BRLeggiRighe {
public static void main(String[] args) throws IOException {
// crea un BufferedReader usando System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, System.console().charset()));
String str;
System.out.println("Inserisci righe di testo.");
System.out.println("Inserisci 'stop' per uscire.");
do {
str = br.readLine();
System.out.println(str);
} while (!str.equals("stop"));
}
}
Un possibile output di questo programma è:
Inserisci righe di testo.
Inserisci 'stop' per uscire.
Ciao
Ciao
Come stai?
Come stai?
stop
stop
L'esempio successivo crea un piccolo editor di testo. Crea un array di oggetti String
e poi legge righe di testo, memorizzando ogni riga nell'array. Leggerà fino a 100
righe o finché non inseriamo "stop
". Usa un BufferedReader
per leggere dalla console.
// Un piccolo editor.
import java.io.*;
class PiccoloEditor {
public static void main(String[] args) throws IOException {
// crea un BufferedReader usando System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, System.console().charset()));
String[] str = new String[100];
System.out.println("Inserisci righe di testo.");
System.out.println("Inserisci 'stop' per uscire.");
for (int i = 0; i < 100; i++) {
str[i] = br.readLine();
if (str[i].equals("stop"))
break;
}
System.out.println("\nEcco il tuo file:");
// visualizza le righe
for (int i = 0; i < 100; i++) {
if (str[i].equals("stop"))
break;
System.out.println(str[i]);
}
}
}
Ecco un esempio di esecuzione:
Inserisci righe di testo.
Inserisci 'stop' per uscire.
Ciao, come stai?
Tutto bene?
Oggi è una bella giornata
stop
Ecco il tuo file:
Ciao, come stai?
Tutto bene?
Oggi è una bella giornata