- Figura 1 -
Fluxul este un concept situat pe un nivel înalt de abstractizare, fiind privit ca o simplă succesiune de octeți sau de caractere care se transmite între sursă și destinație. Nu prezintă importanță nici natura sursei sau a destinației, nici modul în care trebuie interpretată secvența de octeti sau de caractere respectivă. De exemplu, un grup de 32 de octeți transmiși între sursă și destinație poate să reprezinte 32 de caractere ASCII sau 16 caractere Unicode sau 8 numere de tip int sau 4 numere de tip double etc. Această abstractizare permite să se trateze în mod unitar toate tipurile de transmisii de date. |
Se disting doua feluri de fluxuri: de ieșire și de intrare. Pentru un proces dat, toate fluxurile transmise de acesta către exterior se numesc fluxuri de ieșire, iar cele primite din exterior se numesc fluxuri de intrare. În consecință, același flux este de ieșire în raport cu sursa și de intrare în raport cu destinația.
Principalele operații care au loc asupra unui flux sunt:
La sursă (flux de ieșire) | La destinație (flux de intrare) |
- Deschiderea fluxului - cât timp (există date de transmis) scriere în flux -Închiderea fluxului |
-Deschiderea fluxului - cât timp (există date de citit) citire din flux -Închiderea fluxului |
Programatorului procesului sursă îi revine obligația de a pregăti, sub forma unei succesiuni de caractere sau de octeți, datele care urmează a fi transmise pe fluxul de ieșire. Interpretarea și tratarea datelor conținute în flux se face de către procesul de destinație, deci întreaga responsabilitate îi revine celui care programează acest proces. Desigur că este necesar ca interpretarea datelor din flux la destinație să corespundă cu cea de la sursă. Programarea operațiilor de intrare/ieșire poate fi destul de complicată, dar în limbajul Java ea este totuși ușurată de existența unui număr destul de mare de clase cu această destinație, grupate în pachetul java.io.
- Figura 2 - Ierarhia claselor pentru fluxuri de intrare de
caractere
- Figura 3 - Ierarhia claselor pentru fluxuri de ieșire de caractere
- Figura 4 - Ierarhia claselor pentru fluxuri de intrare de octeți
- Figura 5 - Ierarhia claselor pentru fluxuri de ieșire de octeti
Se observă corespondența între clasele de fluxuri de intrare și de
ieșire în cadrul aceleeași categorii de fluxuri. De exemplu, în cazul
fluxurilor de caractere, unui BufferedReader îi corespunde un
BufferedWriter, unui CharArrayReader îi corespunde un CharArrayWriter
etc. În mod similar, în cazul fluxurilor de octeți, unui FileInputStream
îi corespunde un FileOutputStream, unui PipedInputStream îi corespunde
un PipedOutputStream etc. Aceasta reflectă "simetria" operațiilor de
intrare și de ieșire. Există totuși și clase de intrare fără
corespondent la ieșire (de exemplu StringBufferInputStream sau
PushbackInputStream) sau clase de ieșire fără corespondent la intrare
(de exemplu PrintStream).
În JDK 1.0 existau numai clasele de fluxuri de octeți. Fluxurile de caractere au fost introduse începand cu JDK 1.1. În prezent se folosesc ambele categorii de fluxuri. Pentru transmiterea textelor sau a datelor reprezentate în format extern și codificate în Unicode este preferabil, evident, să se folosească fluxuri de caractere. Pentru transmiterea datelor codificate binar sau a textelor în care caracterele sunt codificate pe un octet (de exemplu în codul ASCII) este preferabilă folosirea fluxurilor de octeți. |
Fluxurile pot fi înlănțuite, astfel încât ieșirea unui flux poate fi intrare a altui flux. Astfel, în Figura 6 este dată schema unei înlănțuiri de fluxuri de intrare: ieșirea fluxului InputStream (sub forma de fluxului de octeți flux1) este dată la intrarea fluxului InputStreamReader, care o convertește în fluxul de caracrtere flux2, iar acesta - la rândul lui - este preluat fe fluxul de intrare de caractere cu zonă tampon BufferedReader.
- Figura 6- Înlănțuire de fluxuri de intrare
În Figura 7 este reprezentată o înlănțuire similară de fluxuri de ieșire: ieșirea fluxului de caractere BufferedWriter este aplicată la intrarea fluxului OutputStreamWriter, iar acesta face conversia într-un flux de octeți, pe care îl transmite la un OutputStream (de exemplu la un PrintStream sau la un FileOutputStream).
- Figura 7 - Înlănțuire de fluxuri de ieșire
Având în vedere complexitatea programării operațiilor de intrare/ieșire, în cele ce urmează vom căuta să facem o prezentare graduală, de la simplu la complex. Vom începe însă cu prezentarea comparativă a claselor abstracte care constituie rădăcinile celor patru ierarhii de clase de fluxuri. Aceasta ne va permite să ne formăm o vedere de ansamblu asupra principalelor metode folosite în lucrul cu fluxuri.