Bună! Lecția de astăzi va fi împărțită în două părți pentru comoditate. Vom repeta câteva subiecte vechi pe care le-am atins anterior și vom lua în considerare câteva funcții noi :) Să începem cu prima. Ai deja o clasă ca
Desigur,
Deci de ce avem nevoie pentru ca acest lucru să se întâmple? În primul rând, avem nevoie de un nou
BufferedReader
de multe ori. Sper că nu ai avut timp să uiți această afirmație:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Înainte de a citi mai departe, încercați să vă amintiți de ce este responsabilă fiecare componentă — System.in
, InputStreamReader
, — și de ce este necesară. BufferedReader
Ți-ai amintit? Dacă nu, nu vă faceți griji. :) Dacă ați uitat ceva, recitiți această lecție , care este dedicată orelor de citire. Ne vom aminti pe scurt ce poate face fiecare dintre ei. System.in
— acesta este un flux pentru primirea datelor de la tastatură. În principiu, ar fi suficient să implementezi logica necesară citirii textului. Dar, după cum vă amintiți, System.in
poate citi doar octeți, nu caractere:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Dacă executăm acest cod și introducem litera chirilică „E”, rezultatul va fi:
Й
208
153
10
Caracterele chirilice ocupă 2 octeți în memorie și sunt afișate pe ecran. Numărul 10 este reprezentarea zecimală a unui caracter de avans de linie, adică de la apăsarea Enter. Citirea octeților este o plăcere, așa că utilizarea System.in
nu este foarte convenabilă. Pentru a citi corect literele chirilice (și altele), folosim InputStreamReader
ca înveliș:
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);
}
}
}
Introducem aceeași literă „E”, dar rezultatul este diferit de data aceasta:
Й
1049
10
InputStreamReader
a convertit doi octeți (208 și 153) la un singur număr 1049. Acesta este ceea ce înseamnă a citi caractere. 1049 corespunde literei chirilice „Й”. Ne putem convinge cu ușurință că acest lucru este adevărat:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Ieșire din consolă:
Й
Și ca forBufferedReader
(și în general, BufferedAnythingYouWant
), clasele tampon sunt folosite pentru a optimiza performanța. Accesarea unei surse de date (fișier, consolă, resursă web) este destul de costisitoare din punct de vedere al performanței. Prin urmare, pentru a reduce numărul de accesări, BufferedReader
citește și acumulează date într-un buffer special și le obținem de acolo. Ca rezultat, numărul de accesări la care sursa de date este redusă - posibil cu câteva ordine de mărime! O altă BufferedReader
caracteristică și avantajul său față de cele obișnuite InputStreamReader
este metoda extrem de utilă readLine()
, care citește linii întregi de date, nu numere individuale. Acest lucru, desigur, este foarte convenabil atunci când aveți de-a face cu texte mari. Iată cum arată rândurile de citit:
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 ("The user entered the following text:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone

BufferedReader
este foarte flexibil. Nu te limitezi la lucrul cu tastatura. De exemplu, puteți citi datele direct de pe web, pur și simplu trecând adresa URL necesară unui cititor:
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();
}
}
Puteți citi datele dintr-un fișier trecând calea fișierului:
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();
}
}
Înlocuirea System.out
Acum să aruncăm o privire la o capacitate interesantă la care nu am atins-o până acum. După cum vă amintiți cu siguranță,System
clasa are două câmpuri statice - System.in
și System.out
. Acești frați gemeni sunt obiecte ale fluxului. System.in
este un InputStream
. Și System.out
este un PrintStream
. Chiar acum, vom vorbi despre System.out
. Dacă intrăm în System
codul sursă al clasei, vedem asta:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Astfel, System.out
este pur și simplu o variabilă statică obișnuită aSystem
clasei. Nu e nimic magic în asta :) Variabila out
este o PrintStream
referință. Iată o întrebare interesantă: Când System.out.println()
este executat, de ce exact ieșirea merge la consolă și nu în altă parte? Și asta se poate schimba cumva? De exemplu, să presupunem că vrem să citim date din consolă și să le scriem într-un fișier text. Este posibil să implementați cumva acest lucru pur și simplu folosind System.out
mai degrabă decât clase suplimentare de cititor și scriitor? Într-adevăr, este :) Și o putem face chiar dacă System.out
variabila este marcată cu final
modificatorul! 
PrintStream
obiect care să îl înlocuiască pe cel actual. Obiectul curent, setat înSystem
clasa în mod implicit, nu servește scopurilor noastre: indică către consolă. Trebuie să creați unul nou care să trimită către un fișier text — „destinația” pentru datele noastre. În al doilea rând, trebuie să înțelegem cum să atribuim o nouă valoare variabilei System.out
. Nu puteți utiliza un operator de atribuire simplu, deoarece variabila este marcată final
. Să lucrăm înapoi de la final. După cum se întâmplă, System
clasa are metoda de care avem nevoie: setOut()
. Preia un PrintStream
obiect și îl setează ca destinație pentru ieșire. Tocmai de asta avem nevoie! Tot ce rămâne este să creezi un PrintStream
obiect. Acest lucru este, de asemenea, ușor:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Codul complet va arăta astfel:
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/* Save the current value of System.out in a separate variable so that later
we can switch back to console output */
PrintStream console = System.out;
// Assign a new value to System.out
System.setOut(filePrintStream);
System.out.println("This line will be written to the text file");
// Restore the old value of System.out
System.setOut(console);
System.out.println("But this line will be output to the console!");
}
}
Ca rezultat, primul șir este scris în fișierul text, iar al doilea este afișat în consolă :) Puteți copia acest cod în IDE-ul dvs. și îl puteți rula. Deschideți fișierul text și veți vedea că șirul a fost scris cu succes acolo :) Cu asta, lecția noastră a ajuns la sfârșit. Astăzi ne-am amintit cum să lucrăm cu fluxurile și cititorii. Ne-am amintit cum diferă unul de celălalt și am aflat despre câteva capacități noi ale System.out
, pe care le-am folosit aproape în fiecare lecție :) Până la următoarele lecții!
Mai multe lecturi: |
---|
GO TO FULL VERSION