JavaRush /Java Blog /Random-IT /Lettura da tastiera - “lettori”

Lettura da tastiera - “lettori”

Pubblicato nel gruppo Random-IT
Ciao! Nelle lezioni e nelle attività, abbiamo imparato come inviare i dati alla console e viceversa: leggere i dati dalla tastiera. Lettura da tastiera - “lettori” - 1Hai anche imparato a usare una costruzione complessa per questo:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Ma non abbiamo ancora risposto a una domanda.

Come funziona?

In effetti, qualsiasi programma molto spesso non esiste da solo. Può comunicare con altri programmi, sistemi, Internet, ecc. Con la parola “comunicare” intendiamo innanzitutto “scambiare dati”. Cioè, ricevi alcuni dati dall'esterno e, al contrario, invia i tuoi dati da qualche parte. Esistono molti esempi di scambio di dati tra programmi, anche nella vita di tutti i giorni. Quindi, su molti siti, invece di registrarti, puoi accedere utilizzando il tuo account Facebook o Twitter. In questa situazione, due programmi, ad esempio Twitter e il sito in cui stai tentando di registrarti, si scambiano i dati necessari tra loro, dopodiché vedi il risultato finale: autorizzazione riuscita. Il termine “ flusso ” viene spesso utilizzato per descrivere il processo di scambio dei dati nella programmazione . Da dove viene questo nome? Il “flusso” è più associato a un fiume o ruscello che alla programmazione. In effetti, questo non è senza motivo :) Uno stream è, in sostanza, un pezzo di dati in movimento. Cioè, nella programmazione, non è l'acqua che “scorre” lungo il flusso, ma i dati sotto forma di byte e caratteri. Da un flusso di dati, possiamo ricevere dati in parti e farci qualcosa. Ancora una volta, usiamo l’analogia dello “scorrere dell’acqua”: puoi raccogliere l’acqua da un fiume per cucinare la zuppa, spegnere un fuoco o innaffiare i fiori. Utilizzando gli stream, puoi lavorare con qualsiasi fonte di dati: Internet, il file system del tuo computer o qualcos'altro, non importa. Gli stream sono uno strumento universale. Permettono al programma di ricevere dati da qualsiasi luogo (flussi in entrata) e inviarli ovunque (flussi in uscita). Il loro compito è uno: prendere i dati in un posto e inviarli a un altro. I flussi si dividono in due tipologie:
  1. Flusso in entrata ( Input ): utilizzato per ricevere dati
  2. Flusso in uscita ( Output ) - per l'invio di dati.
Il flusso di dati in entrata in Java viene implementato nella classe InputStreame il flusso di dati in uscita nella classe OutputStream. Ma c'è un altro modo per dividere i thread. Sono divisi non solo in entranti e uscenti, ma anche in byte e caratteri . Qui il significato è chiaro senza spiegazioni: un flusso di byte trasmette informazioni sotto forma di un insieme di byte e un flusso di caratteri trasmette informazioni sotto forma di un insieme di caratteri. In questa lezione entreremo nei dettagli sui flussi in entrata. E allegherò le informazioni sui collegamenti in uscita alla fine e potrai leggerle tu stesso :) Quindi, il nostro codice:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Probabilmente hai pensato anche durante la lettura delle lezioni che fosse piuttosto spaventoso? :) Ma questo solo finché non capiremo come funziona questa cosa. Risolviamolo adesso! Cominciamo dalla fine. System.inè un oggetto della classe InputStreamdi cui abbiamo parlato all'inizio. Questo è un flusso in entrata ed è legato al dispositivo di input del sistema: la tastiera. A proposito, lo conosci indirettamente. Dopotutto, usi spesso il suo "collega" nel tuo lavoro - System.out! System.out- questo è un flusso di output dei dati di sistema , viene utilizzato per l'output sulla console proprio nello stesso metodo System.out.println()che usi costantemente :) System.out- un flusso per inviare dati alla console e System.in- per ricevere dati dalla tastiera. E' semplice :) Inoltre: per leggere i dati dalla tastiera possiamo fare a meno di questa grande costruzione e scrivere semplicemente: 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);
       }
   }
}
Nella classe InputStream(e System.in, lasciatemelo ricordare, è un oggetto della classe InputStream) c'è un metodo read()che permette di leggere i dati. Un problema: legge byte , non caratteri . Proviamo a leggere la lettera russa "Ya" dalla tastiera. Uscita console:
Я
208
175
10
Le lettere russe occupano 2 byte nella memoria del computer (a differenza delle lettere inglesi, che ne occupano solo 1). In questo caso sono stati letti 3 byte dallo stream: i primi due rappresentano la nostra lettera “I”, e l'altro è l'interruzione di riga (Invio). Pertanto, l'opzione di utilizzare "nudo" System.innon è adatta a noi. Gli esseri umani (con rare eccezioni!) non possono leggere i byte. È qui che la lezione successiva ci viene in aiuto InputStreamReader:! Scopriamo che tipo di animale è questo.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Passiamo il flusso System.inal file InputStreamReader. In generale, se traduci il suo nome in russo, tutto sembra ovvio: "lettore di flussi in entrata". In realtà è proprio a questo che serve! Creiamo un oggetto di classe InputStreamReadere gli passiamo un flusso in entrata da cui dovrebbe leggere i dati. In questo caso...
new InputStreamReader(System.in)
...gli diciamo: "leggerai i dati dal flusso di input del sistema (tastiera)." Ma questa non è la sua unica funzione! InputStreamReadernon solo riceve dati dal flusso. Converte anche i flussi di byte in flussi di caratteri . In altre parole, non dovrai più preoccuparti di tradurre i dati letti dal linguaggio "computer" al linguaggio "umano": InputStreamReaderfarà tutto per te. InputStreamReader, ovviamente, può leggere i dati non solo dalla console, ma anche da altri luoghi. Ad esempio, dal 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 abbiamo creato un flusso di dati in entrata FileInputStream(questa è una delle varietà InputStream), gli abbiamo passato il percorso del file e il flusso stesso InputStreamReader'y. Ora sarà in grado di leggere i dati da questo file, se il file in questo percorso esiste, ovviamente. Per leggere i dati (non importa da dove, dalla console, da un file o da qualsiasi altra parte), la classe InputStreamReaderutilizza anche l'estensione read(). Qual è la differenza tra System.in.read()e InputStreamReader.read()? Proviamo a contare la stessa lettera “I” utilizzando InputStreamReader. Permettetemi di ricordarvi che questo è quello che ho pensato System.in.read():
Я
208
175
10
Come può fare lo stesso lavoro InputStreamReader?
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:
Я
1071
10
La differenza è immediatamente visibile. L'ultimo byte - quello delle interruzioni di riga - è rimasto invariato (il numero 10), ma la lettera letta “I” è stata convertita in un unico codice “1071”. Questa è la lettura per simboli! Se all'improvviso non credi che il codice 1071 significhi la lettera "I", è facile verificarlo :)
import java.io.IOException;

public class Main {

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

       char x = 1071;
       System.out.println(x);
   }
}
Uscita console:

Я
Ma se InputStreamReaderè così buono, perché te ne serve di più BufferedReader? InputStreamReaderpuò sia leggere i dati che convertire i byte in caratteri: cos'altro ci serve? Perché un altro lettore? :/ La risposta è molto semplice: per una maggiore produttività e una maggiore comodità . Cominciamo dalle prestazioni. Durante la lettura dei dati, BufferedReader utilizza un'area speciale, un buffer, dove "aggiunge" i caratteri letti. Di conseguenza, quando avremo bisogno di questi caratteri nel programma, verranno presi dal buffer e non direttamente dalla fonte dati (tastiera, file, ecc.), e questo fa risparmiare molte risorse. Per capire come funziona, immagina, ad esempio, il lavoro di un corriere in una grande azienda. Il corriere siede in ufficio e aspetta che gli vengano portati i pacchi per la consegna. Ogni volta che riceve un nuovo pacco, può subito mettersi in viaggio. Ma potrebbero esserci molti pacchi durante il giorno e dovrà viaggiare ogni volta tra l'ufficio e gli indirizzi. Invece il corriere ha messo in ufficio una scatola dove tutti potevano riporre i propri pacchi. Ora il corriere può prendere con calma la scatola e recarsi agli indirizzi: risparmierà molto tempo, perché non dovrà tornare in ufficio ogni volta. La scatola in questo esempio è proprio il buffer e l'ufficio è l'origine dati. È molto più facile per un corriere prendere una lettera da una cassetta comune al momento della consegna piuttosto che recarsi ogni volta in ufficio. Si risparmierà anche benzina. È lo stesso in un programma: è molto meno dispendioso in termini di risorse prendere i dati dal buffer, piuttosto che accedere ogni volta all'origine dati. Ecco perché BufferedReader+ InputStreamReaderfunziona più velocemente di solo InputStreamReader. Abbiamo risolto il problema delle prestazioni, ma per quanto riguarda la comodità? Il vantaggio principale è che BufferedReaderpuò leggere i dati non solo un carattere alla volta (anche se read()ha anche un metodo per questo scopo), ma anche intere righe! Questo viene fatto usando il readLine();
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);
   }
}
Uscita console:
JavaRush is the best site to learn Java!
Мы считали с клавиатуры эту строку:
JavaRush — лучший сайт для изучения Java!
Ciò è particolarmente utile quando si leggono grandi quantità di dati. È ancora possibile leggere una o due righe di testo carattere per carattere. Ma contare "Guerra e pace" una lettera alla volta sarà alquanto problematico :) Ora il lavoro dei thread ti è diventato molto più chiaro. Per ulteriori approfondimenti, ecco una fonte aggiuntiva per te: Qui puoi leggere di più sui flussi in entrata e in uscita. Recensione video BufferedReaderdi uno dei nostri studenti. Sì, sì, i nostri studenti non solo imparano da soli, ma registrano anche video educativi per gli altri! Non dimenticare di mettere mi piace e di iscriverti al nostro canale :)
È meglio abituarsi a leggere la documentazione ufficiale fin dall'inizio dei propri studi. È la principale fonte di conoscenza della lingua e la maggior parte delle risposte si possono sempre trovare lì.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION