1. InputStreamReader
clasa
O altă caracteristică interesantă a fluxurilor este că puteți combina mai multe fluxuri împreună în lanțuri . Un flux poate citi date nu numai din sursa sa internă de date, ci și din alt flux .
Acesta este un mecanism foarte puternic în Java, care face posibilă crearea unor scenarii complexe de citire a datelor prin conectarea unui flux la altul. O astfel de schemă arată astfel:
Când un program citește date dintr-un flux de date, fluxul de date citește la rândul său datele din sursa sa de date, care este un alt flux de date sau un fișier, de exemplu.
În plus, fiecare flux de date nu numai că citește și emite date, dar poate și să le transforme sau să efectueze diverse operații asupra acestuia. Un bun exemplu de astfel de „flux intermediar” este InputStreamReader
clasa.
Știm deja o clasă numită FileReader
- este o clasă Reader
care citește date dintr-un fișier. Și InputStreamReader
de unde își iau datele? Așa este — dintr-un InputStream
.
Când creați un InputStreamReader
obiect, trebuie să treceți un InputStream
obiect sau una dintre clasele sale descendente. Exemplu:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
Clasa InputStreamReader
are toate metodele pe care le Reader
are clasa și funcționează exact în același mod.
Principala diferență dintre InputStreamReader
clasă și, să zicem, FileReader
este de unde citesc datele. FileReader
citește date dintr-un fișier (duh — de aceea se numește FileReader
), dar InputStreamReader
citește date dintr-un fișier InputStream
.
Când citiți un caracter dintr-un FileReader
obiect folosind read()
metoda, acesta citește, la rândul său, doi octeți din fișierul de pe disc și îi returnează ca chars
.
Când citiți un caracter dintr-un InputStreamReader
obiect folosind read()
metoda, acesta citește, la rândul său, doi octeți din FileInputStream
obiectul care i-a fost transmis, care la rândul său citește datele din fișier. Rezultatul este un lanț de apeluri la read()
metode.
2. BufferedReader
clasa
O altă clasă interesantă pe care probabil o vei folosi foarte mult este BufferedReader
. Acesta este, de asemenea, un „flux intermediar” care citește date dintr-un alt flux.
După cum sugerează și numele, BufferedReader
clasa este o subclasă Reader
și vă permite să citiți caractere . Dar ceea ce este cel mai interesant este că trebuie să îi treci și o sursă de date sub forma unui flux din care pot fi citite caracterele , adică un flux care moștenește Reader
clasa.
Care e ideea? Spre deosebire de InputStreamReader
, BufferedReader
clasa nu convertește octeții în caractere: nu convertește absolut nimic. În schimb, pune în tampon datele .
Când un program citește un singur caracter dintr-un BufferedReader
obiect, obiectul citește o gamă largă de caractere din fluxul sursă dintr-o dată. Și le stochează intern.
Când următorul caracter este citit din BufferedReader
obiect, pur și simplu preia următorul caracter din matricea sa de buffer intern și îl returnează fără a accesa sursa de date. Numai când toate caracterele din buffer sunt epuizate, se citește într-o altă serie mare de caractere.
Clasa BufferedReader
are, de asemenea, o metodă foarte utilă — String readLine()
, care vă permite să citiți șiruri întregi de date din fluxul sursă dintr-o dată. Puteți folosi această metodă pentru, de exemplu, să citiți un fișier și să afișați conținutul acestuia pe ecran, linie cu linie. Exemplu:
Am scris în mod special un cod compact pentru a ilustra cât de convenabil poate fi acest lucru. Acest cod ar putea fi scris și cu puțin mai multe detalii.
|
Creați un FileReader obiect. Sursa de date este un fișier. Creați un BufferedReader obiect. Sursa de date este un FileReader . Atâta timp cât mai există date în cititor Citiți o linie Afișați linia |
Dacă înlănțuiți mai multe fluxuri, atunci close()
metoda trebuie apelată doar pe unul dintre ele. Fluxul respectiv va apela metoda pe sursa sa de date și așa mai departe, până când close()
este apelat pe fluxul de date final.
3. Citirea de pe consolă
Și încă un fapt interesant: Scanner
clasa nu este altceva decât un flux de intrare intermediar care citește date din System.in
, care este și un flux de date.
Iată două moduri de a citi o linie din consolă:
Clasa de scaner | Clasele BufferedReader și BufferedWriter |
---|---|
|
|
Prietenul nostru nu este altceva decât o variabilă statică a clasei. Este un al cărui nume este .System.in
in
System
InputStream
in
Deci, aproape de la începutul studiilor tale Java pe CodeGym, ai lucrat cu fluxuri de date și ai construit lanțuri din ele. Dar acum o vei face mai conștient.
GO TO FULL VERSION