CodeGym /Java Blog /Random-IT /Lettura dalla tastiera: "lettori"
John Squirrels
Livello 41
San Francisco

Lettura dalla tastiera: "lettori"

Pubblicato nel gruppo Random-IT
CIAO! Le lezioni e le attività del Livello 3 ti hanno insegnato come visualizzare elementi sulla console e, spostandoti nella direzione opposta, come leggere i dati dalla tastiera.
Lettura dalla tastiera: "lettori" - 1
Hai persino imparato a utilizzare il seguente costrutto complesso per ottenere questo risultato:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Ma c'è una domanda a cui non abbiamo ancora risposto.

Come funziona nel mondo?

In realtà, raramente i programmi sono del tutto indipendenti. Comunicano con altri programmi, sistemi, Internet, ecc. Con "comunicare" intendiamo principalmente "scambiare dati". Cioè, ricevono alcuni dati esterni e inviano anche dati di programma interni da qualche parte. Esempi di programmi che scambiano dati abbondano nella vita di tutti i giorni. Ad esempio, molti siti Web ti consentono di accedere utilizzando il tuo account Facebook o Twitter invece di registrarti. In questa situazione, due programmi (ad esempio Twitter e il sito Web a cui stai effettuando l'accesso) si scambiano i dati necessari. Il risultato finale è che hai eseguito correttamente l'accesso. La parola "stream"è usato per descrivere il processo di scambio di dati. Da dove viene questo nome? Nella tua esperienza, un "flusso" può essere più associato ai fiumi che alla programmazione. Non è un caso :) Un flusso è, in sostanza, un pezzo di dati in movimento. In altre parole, nella programmazione non è l'acqua che scorre, ma piuttosto i dati sotto forma di byte e caratteri. Possiamo ricevere bit di dati da un flusso di dati e quindi utilizzarli. Ancora una volta, useremo l'analogia acqua/flusso: puoi raccogliere l'acqua da un fiume per fare una zuppa, spegnere un fuoco o innaffiare i tuoi fiori. Gli stream ti consentono di lavorare con qualsiasi fonte di dati: che si tratti di Internet, del file system del tuo computer o di qualcos'altro, non fa differenza. Gli stream sono uno strumento universale. Consentono a un programma di ricevere dati da qualsiasi luogo (flussi di input) e di inviarli ovunque (flussi di output). Il loro compito è lo stesso: prendere i dati da un posto e inviarli a un altro. Esistono due tipi di flussi:
  1. I flussi di input vengono utilizzati per ricevere i dati
  2. I flussi di output servono per l'invio di dati.
In Java, questi flussi sono implementati dalle classi InputStreame OutputStream. Ma i flussi possono essere classificati in un altro modo. Oltre ai flussi di input e output, si parla anche di flussi di byte e flussi di caratteri . Il significato qui dovrebbe essere abbastanza chiaro: un flusso di byte invia informazioni come un insieme di byte, mentre un flusso di caratteri le invia come un insieme di caratteri. In questa lezione ci soffermeremo sui flussi di input. Metterò un collegamento con le informazioni sui flussi di output alla fine della lezione. Puoi leggerlo da solo :) Ora dai un'occhiata a questo codice:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Durante le lezioni, non hai pensato che questa battuta fosse abbastanza intimidatoria? :) Non sarà così una volta che avremo esplorato come funziona. Mettiamo le cose a posto. Inizieremo dalla fine. System.inè un InputStreamoggetto, un'istanza della classe di cui abbiamo parlato all'inizio. È un flusso di input collegato a un dispositivo di input del sistema (la tastiera). A proposito, conosci indirettamente questo stream. Dopotutto, usi spesso il suo "collega" — System.out! System.outè il flusso di output del sistema . Viene utilizzato per inviare dati alla console tramite il tuo metodo preferito System.out.println(), che usi costantemente :) System.outè un flusso per inviare dati alla console, mentreSystem.inserve per ottenere dati dalla tastiera. È tutto semplice :) Inoltre, possiamo leggere i dati dalla tastiera senza questo enorme costrutto. Possiamo semplicemente scrivere: System.in.read();

public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
La InputStreamclasse (ricorda, System.inè un InputStreamoggetto) ha un read()metodo che ti permette di leggere i dati. C'è un problema: legge bytes , non characters . È noioso usare solo lettere inglesi, quindi proviamo a leggere il carattere cinese "魚" dalla tastiera (basta copiare questa lettera da qui e incollarla sulla console usando ctrl + v su PC o Command + v su Mac). Questo carattere significa 'un pesce' tra l'altro. Uscita console: 233 173 154 10 Questo simbolo e molti altri cinesi occupano 3 byte nella memoria del computer (a differenza delle lettere latine, che occupano solo 1 byte). In questo caso vengono letti 4 byte dallo stream: i primi tre rappresentano il carattere "魚" e l'altro byte rappresenta una nuova riga (Invio). Di conseguenza, System.innella sua forma disadorna non è un'opzione per noi. Gli esseri umani (con rare eccezioni!) non sanno leggere i byte. Ma la InputStreamReaderclasse viene in soccorso! Vediamo che tipo di animale è.

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Passiamo System.inall'oggetto InputStreamReader . Lo dice il nome della classe! Creiamo un InputStreamReaderoggetto e gli passiamo un flusso di input da cui leggerà i dati. In questo caso...

new InputStreamReader(System.in)
... gli diciamo "leggerai i dati dal flusso di input del sistema (dalla tastiera)". Ma questa non è la sua unica funzione! Il InputStreamReadernon solo riceve i dati dal flusso. Converte anche flussi di byte in flussi di caratteri . In altre parole, non è più necessario convertire i dati da "uno e zero" in un "linguaggio leggibile dall'uomo". InputStreamreaderfa tutto per te. Ovviamente InputStreamReadernon si limita alla lettura dei dati dalla console. Può anche leggere dati da altri luoghi. Ad esempio, da un file:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
Qui creiamo un FileInputStream(un sapore di InputStream), passiamo il percorso del file e passiamo il flusso stesso al file InputStreamReader. Ora sarà in grado di leggere i dati dal file (se un file esiste effettivamente nel percorso, ovviamente). Usiamo anche il metodo InputStreamReaderdella classe read()per leggere i dati (l'origine dei dati non ha importanza: la console, un file o da qualche altra parte). Qual è la differenza tra System.in.read()e InputStreamReader.read()?\ Proviamo nuovamente a leggere il carattere "魚" con un InputStreamReader. Vi ricordo cosa è stato effettivamente letto da System.in.read(): 233 173 154 10 E come funziona InputStreamReaderlo stesso?

public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
Uscita console: 39770 10 La differenza è immediatamente evidente. L'ultimo byte (che rappresenta la nuova riga) rimane invariato (il numero 10), ma il carattere "魚" è stato convertito in un unico codice "39770". Ecco cosa significa leggere i caratteri! Se non credi che 39770 rappresenti la lettera "魚", è facile convincerti :)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 39770;
       System.out.println(x);
   }
}
Uscita console: Ma se InputStreamReaderè così grande, perché abbiamo bisogno anche di BufferedReader? InputStreamReadersa leggere i dati e convertire i byte in caratteri. Cosa potremmo chiedere di più? Perché un altro lettore? :/ La risposta è molto semplice: per maggiori prestazioni e praticità . Partiamo dalle prestazioni. Quando BufferedReaderlegge i dati, utilizza un'area speciale chiamata buffer, dove "memorizza" i caratteri che legge. In definitiva, quando questi caratteri sono necessari nel programma, verranno prelevati dal buffer, non direttamente dall'origine dati (tastiera, file, ecc.). Ciò consente di risparmiare molte risorse. Per capire come funziona, immagina un corriere in una grande azienda. Il corriere è seduto in un ufficio, in attesa che qualcuno porti i pacchi per la consegna. Ogni volta che riceve un nuovo pacco, può mettersi subito in viaggio. Ma potrebbero esserci molti pacchi durante il giorno. Avrebbe dovuto fare molti viaggi tra l'ufficio e gli indirizzi di consegna. Invece, il corriere mette una scatola nel suo ufficio. Tutti mettono i loro pacchi nella scatola. Ora il corriere può tranquillamente prendere la scatola e spostarsi da un indirizzo all'altro. Ciò consente di risparmiare molto tempo, perché non deve tornare in ufficio ogni volta. In questo esempio, la scatola è solo un buffer e l'ufficio è un'origine dati. È molto più facile per il corriere prelevare i pacchi da un'unica scatola quando effettua le consegne piuttosto che tornare in ufficio ogni volta. Risparmierà anche benzina. Allo stesso modo, in un programma è molto meno dispendioso in termini di risorse prelevare dati da un buffer piuttosto che fare riferimento ogni volta all'origine dati. Di conseguenza,BufferedReader+ InputStreamReaderè più veloce che InputStreamReaderda solo . Abbiamo considerato le prestazioni. E la convenienza? Il vantaggio principale è che Bufferedreaderpuò leggere i dati non solo un carattere alla volta (sebbene possa farlo con il suo read()metodo), ma anche intere righe alla volta! Questo viene fatto usando il readLine()metodo;

public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("We read this line from the keyboard:");
       System.out.println(s);
   }
}
Output della console: CodeGym è il miglior sito Web per l'apprendimento di Java! Leggiamo questa riga dalla tastiera: CodeGym è il miglior sito web per imparare Java! Ciò è particolarmente utile durante la lettura di grandi quantità di dati. La lettura di una o due righe di testo carattere per carattere è ancora fattibile. Ma leggere in "Guerra e pace" una lettera alla volta sarebbe alquanto problematico :)
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION