Ciao! La conferenza di oggi sarà divisa in due parti. Ripeteremo alcuni dei vecchi argomenti che abbiamo già toccato in precedenza e esamineremo alcune nuove funzionalità :) Iniziamo con il primo. La ripetizione è la madre dell'apprendimento :) Hai già utilizzato una classe come
BufferedReader
. Spero che tu non abbia ancora dimenticato questo comando:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Prima di continuare a leggere, cerca di ricordare di cosa System.in, InputStreamReader, BufferedReader
è responsabile ciascun componente ( ) e a cosa serve. Accaduto? In caso contrario, non preoccuparti :) Se a questo punto hai dimenticato qualcosa, rileggi nuovamente questa lezione dedicata ai lettori. Ricordiamo brevemente cosa può fare ciascuno di loro. System.in
è un thread per ricevere dati dalla tastiera. In linea di principio, per attuare la logica della lettura del testo, ce ne basterebbe uno. Ma, come ricorderete, System.in
può leggere solo byte, non caratteri:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Se eseguiamo questo codice e inseriamo la lettera "Y" nella console, l'output sarà così:
Й
208
153
10
I caratteri cirillici occupano 2 byte in memoria, che vengono visualizzati sullo schermo (e il numero 10 è la rappresentazione in byte di un'interruzione di riga, cioè premendo Invio). Leggere i byte è un vero piacere, quindi usarlo System.in
nella sua forma pura sarà scomodo. Per poter leggere le lettere cirilliche (e non solo) comprensibili a tutti, utilizziamo InputStreamReader
come wrapper:
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);
}
}
}
Se inseriamo nella console la stessa lettera “Y”, il risultato questa volta sarà diverso:
Й
1049
10
InputStreamReader
ha convertito i due byte letti (208, 153) in un singolo numero 1049. Questa è la lettura per caratteri. 1049 corrisponde alla lettera “Y”, che può essere facilmente verificata:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Uscita console:
Й
Ebbene, per quanto riguarda BufferedReader
'a (e in generale - BufferedAnything), le classi bufferizzate vengono utilizzate per ottimizzare le prestazioni. Accedere ad una fonte dati (file, console, risorsa su Internet) è un'operazione piuttosto costosa in termini di prestazioni. Pertanto, per ridurre il numero di tali chiamate, BufferedReader
legge e accumula i dati in un buffer speciale, da dove potremo successivamente riceverli. Di conseguenza, il numero di chiamate alla fonte dati viene ridotto di diverse volte o addirittura di decine di volte! Un'altra caratteristica aggiuntiva di BufferedReader
'a e il suo vantaggio rispetto a normale InputStreamReader
' è il metodo estremamente utile readLine()
che legge i dati come stringhe intere anziché come singoli numeri. Ciò, ovviamente, aumenta notevolmente la comodità quando si implementa, ad esempio, testo di grandi dimensioni. Ecco come sarebbe leggere una riga:
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("Пользователь ввел следующий текст:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Naturalmente BufferedReader
è un meccanismo molto flessibile e consente di lavorare non solo con la tastiera. Puoi leggere i dati, ad esempio, direttamente da Internet semplicemente passando l'URL richiesto al lettore:
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("https://www.oracle.com/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Puoi leggere i dati da un file passandogli il percorso:
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("testFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println (str);
}
reader.close();
}
}
Sostituzione di System.out
Ora diamo un'occhiata a una possibilità interessante che non abbiamo mai toccato prima. Come probabilmente ricorderai,System
ci sono due campi statici nella classe: System.in
e System.out
. Questi fratelli gemelli sono oggetti di classe thread. System.in
- classe astratta InputStream
. Una System.out
classe PrintStream
. Adesso parleremo nello specifico di System.out
. Se entriamo nel codice sorgente della classe System
, vedremo questo:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Quindi, System.out
solo una normale variabile di classe staticaSystem
. Non c'è magia in questo :) La variabile out
appartiene alla classe PrintStream
. Ecco una domanda interessante: perché, durante l'esecuzione del codice, System.out.println()
l'output appare nella console e non da qualche altra parte? Ed è possibile cambiare questo in qualche modo? Ad esempio, vogliamo leggere i dati dalla console e scriverli in un file di testo. È possibile implementare in qualche modo tale logica senza utilizzare classi di lettura e scrittura aggiuntive, ma semplicemente utilizzando System.out
? Ancora il più possibile :) E sebbene la variabile System.out
sia designata da un modificatore final
, possiamo ancora farlo! Allora di cosa abbiamo bisogno per questo? Innanzitutto , abbiamo bisogno di un nuovo oggetto di classe PrintStream
invece di quello attuale. L'oggetto corrente installato nella classe System
per impostazione predefinita non ci soddisfa: punta alla console. Dobbiamo crearne uno nuovo che indichi un file di testo come "destinazione" per i nostri dati. In secondo luogo , è necessario capire come assegnare un nuovo valore a una variabile System.out
. Non puoi farlo semplicemente così, perché è contrassegnato final
. Cominciamo dalla fine. La classe System
contiene esattamente il metodo di cui abbiamo bisogno - setOut()
. Prende un oggetto come input PrintStream
e lo imposta come punto di output. Proprio quello di cui abbiamo bisogno! Non resta che creare l'oggetto PrintStream
. Anche questo è facile da fare:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
L'intero codice sarà simile al seguente:
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/*Сохраним текущее meaning System.out в отдельную переменную, чтобы потом
можно было переключиться обратно на вывод в консоль*/
PrintStream console = System.out;
// Присваиваем System.out новое meaning
System.setOut(filePrintStream);
System.out.println("Эта строка будет записана в текстовый файл");
// Возвращаем System.out старое meaning
System.setOut(console);
System.out.println("А эта строка - в консоль!");
}
}
Di conseguenza, la prima riga verrà scritta in un file di testo e la seconda verrà inviata alla console :) Puoi copiare questo codice sul tuo IDE ed eseguirlo. Aprendo il file di testo, vedrai che la riga richiesta è stata scritta lì con successo :) Questo conclude la lezione. Oggi ci siamo ricordati di come lavorare con stream e lettori, abbiamo ricordato come differiscono l'uno dall'altro e abbiamo appreso nuove funzionalità System.out
che abbiamo utilizzato in quasi ogni lezione :) Ci vediamo alle prossime lezioni!
GO TO FULL VERSION