"Bună ziua, Amigo! Astăzi ne vom familiariza cu fluxurile de intrare/ieșire . Am ales acest subiect în urmă cu câteva zile, dar astăzi îl vom explora în detaliu. Fluxurile de intrare/ieșire sunt împărțite în 4 categorii:"

1) Fluxurile sunt împărțite în funcție de direcția lor: fluxuri de intrare și fluxuri de ieșire

2) Fluxurile sunt împărțite în funcție de tipul lor de date: cele care funcționează cu octeți și cele care lucrează cu caractere .

Aici aceste diviziuni sunt reprezentate într-un tabel:

Flux de intrare Flux de ieșire
Funcționează cu octeți InputStream OutputStream
Lucrează cu personaje Cititor Scriitor

Dacă un obiect implementează interfața InputStream , atunci acceptă capacitatea de a citi secvențial octeți din acesta.

Dacă un obiect implementează interfața OutputStream , atunci acceptă capacitatea de a scrie secvențial octeți în el.

Dacă un obiect implementează interfața Reader , atunci acceptă capacitatea de a citi secvențial caractere (caractere) din acesta.

Dacă un obiect implementează interfața Writer , atunci acceptă capacitatea de a scrie secvențial caractere (caractere) în el.

Fluxuri de intrare/ieșire - 1

Un flux de ieșire este ca o imprimantă. Putem scoate documente la imprimantă. Putem scoate date într-un flux de ieșire.

La rândul său, un flux de intrare poate fi comparat cu un scaner, sau poate cu o priză electrică. Cu un scaner, putem aduce documente pe computer. Sau putem conecta la o priză electrică și primim electricitate de la ea. Putem primi date dintr-un flux de intrare.

„Unde sunt folosite?”

„Aceste clase sunt folosite peste tot în Java. Prietenul nostru familiar System.in este o variabilă statică InputStream numită în clasa System .”

"Serios?! Deci în tot acest timp am folosit un InputStream și nici nu mi-am dat seama. System.out este și un stream?"

„Da, System.out este o variabilă statică PrintStream (un descendent al OutputStream ) din clasa System.”

„Vrei să-mi spui că întotdeauna am folosit fluxuri și nici măcar nu știam asta?”

"Da, și asta ne spune doar cât de convenabile sunt aceste fluxuri. Doar iei unul și folosește-l."

„Dar nu poți spune asta despre System.in. A trebuit să-i adăugăm constant BufferedReader sau InputStreamReader.”

— Este adevărat. Dar au existat și motive pentru asta.

Există o mulțime de tipuri de date și multe modalități de a lucra cu ele. Deci, numărul claselor standard I/O a crescut foarte repede, deși au făcut totul aproape în același mod. Pentru a evita această complexitate, dezvoltatorii Java au folosit principiul abstractizării și au împărțit clasele în multe părți mici.

Dar puteți conecta aceste părți într-un mod coerent și puteți obține funcționalități foarte complexe, dacă aveți nevoie. Uită-te la acest exemplu:

Ieșiți un șir în consolă
System.out.println("Hello");
Stocați fluxul de ieșire al consolei într-o variabilă separată.
Ieșiți un șir în flux.
PrintStream console = System.out;
console.println("Hello");
Creați o matrice dinamică (extindere) de octeți în memorie.
Conectați-l la un nou flux de ieșire (obiect PrintStream).
Ieșiți un șir în flux.
ByteArrayOutputStream stream = new ByteArrayOutputStream();
PrintStream console = new PrintStream(stream);
console.println("Hello");

"Sincer, acesta este ca un set Lego. Numai că nu îmi este clar ce face vreunul din codurile ăsta."

"Nu-ți face griji pentru asta deocamdată. Totul la timpul său."

Acesta este ceea ce vreau să vă amintiți: dacă o clasă implementează interfața OutputStream, puteți scrie octeți în ea. Aproape exact așa cum scoateți date în consolă. Ceea ce face cu el este treaba lui. Cu „kitul nostru Lego”, nu ne pasă de scopul fiecărei piese individuale. Ne pasă de faptul că selecția mare de piese ne permite să construim lucruri atât de interesante.

"Bine. Atunci de unde începem?"