1. InputStreamReader
classe
Un'altra caratteristica interessante dei flussi è la possibilità di combinare più flussi insieme in catene . Un flusso può leggere i dati non solo dalla sua origine dati interna, ma anche da un altro flusso .
Si tratta di un meccanismo molto potente in Java, che consente di creare complessi scenari di lettura dei dati collegando uno stream all'altro. Tale schema è simile a questo:
Quando un programma legge i dati da un flusso di dati, il flusso di dati a sua volta legge i dati dalla sua origine dati, che è ad esempio un altro flusso di dati o un file.
Inoltre, ogni flusso di dati non solo legge e fornisce dati, ma può anche trasformarli o eseguire varie operazioni su di essi. Un buon esempio di tale "flusso intermedio" è la InputStreamReader
classe.
Conosciamo già una classe chiamata FileReader
— è una Reader
che legge i dati da un file. E da dove InputStreamReader
prende i suoi dati? Esatto, da un file InputStream
.
Quando crei un InputStreamReader
oggetto, devi passare un InputStream
oggetto o una delle sue classi discendenti. Esempio:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
La InputStreamReader
classe ha tutti i metodi che Reader
ha la classe e funzionano esattamente allo stesso modo.
La principale differenza tra la InputStreamReader
classe e, diciamo, FileReader
è da dove leggono i dati. FileReader
legge i dati da un file (duh, ecco perché si chiama FileReader
), ma InputStreamReader
legge i dati da un file InputStream
.
Quando leggi un carattere da un FileReader
oggetto usando il read()
metodo, a sua volta legge due byte dal file su disco e li restituisce come chars
.
Quando leggi un carattere da un InputStreamReader
oggetto usando il read()
metodo, a sua volta legge due byte dall'oggetto che FileInputStream
gli è passato, che a sua volta legge i dati dal file. Il risultato è una catena di chiamate ai read()
metodi.
2. BufferedReader
classe
Un'altra classe interessante che probabilmente userai molto è BufferedReader
. Questo è anche un "flusso intermedio" che legge i dati da un altro flusso.
Come suggerisce il nome, la BufferedReader
classe è una sottoclasse di Reader
e ti consente di leggere i caratteri . Ma la cosa più interessante è che devi anche passargli un'origine dati sotto forma di un flusso da cui possono essere letti i caratteri , cioè un flusso che eredita la Reader
classe.
Qual e il punto? A differenza di InputStreamReader
, la BufferedReader
classe non converte i byte in caratteri: non converte nulla. Invece, bufferizza i dati .
Quando un programma legge un singolo carattere da un BufferedReader
oggetto, l'oggetto legge una vasta gamma di caratteri dal suo flusso di origine tutto in una volta. E li memorizza internamente.
Quando il carattere successivo viene letto dall'oggetto BufferedReader
, prende semplicemente il carattere successivo dal suo array di buffer interno e lo restituisce senza accedere all'origine dati. Solo quando tutti i caratteri nel buffer sono esauriti, legge un'altra grande matrice di caratteri.
La BufferedReader
classe ha anche un metodo molto utile — String readLine()
, che ti consente di leggere intere stringhe di dati dal flusso di origine tutto in una volta. Puoi usare questo metodo, ad esempio, per leggere un file e visualizzarne il contenuto sullo schermo riga per riga. Esempio:
Abbiamo specificamente scritto un codice compatto per illustrare quanto questo possa essere conveniente. Questo codice potrebbe anche essere scritto con qualche dettaglio in più.
|
Crea un FileReader oggetto. L'origine dati è un file. Crea un BufferedReader oggetto. L'origine dati è un file FileReader . Finché ci sono ancora dati nel lettore Leggi una riga Visualizza la riga |
Se si concatenano più flussi, il close()
metodo deve essere chiamato solo su uno di essi. Quel flusso chiamerà il metodo sulla sua origine dati e così via, fino a quando non close()
viene chiamato sul flusso di dati finale.
3. Lettura dalla console
E un altro fatto interessante: la Scanner
classe non è altro che un flusso di input intermedio che legge i dati da System.in
, che è anche un flusso di dati.
Ecco due modi per leggere una riga dalla console:
Classe Scanner | Classi BufferedReader e BufferedWriter |
---|---|
|
|
Il nostro amico non è altro che una variabile statica della classe. È un il cui nome è .System.in
in
System
InputStream
in
Quindi quasi dall'inizio dei tuoi studi Java su CodeGym, hai lavorato con flussi di dati e ne hai costruito catene. Ma ora lo farai in modo più consapevole.
GO TO FULL VERSION