Documente Academic
Documente Profesional
Documente Cultură
Un flux care citește date se numește de intrare, iar cel care scrie date se numește de ieșire.
Pentru a aduce informații dintr-un mediu extern , un program Java trebuie să deschidă un
canal de comunicație(flux) de la sursa informațiilor (fișier, memorie, socket, etc) și să
citească secvențial informațiile respective.
Indiferent de tipul informațiilor , citirea/scrierea de pe/către un mediu extern
respectă următorul algoritm:
Clasificarea fluxurilor
Există trei tipuri de clasificare a fluxurilor:
După direcția canalului de comunicație deschis fluxurile se impart în :
fluxuri de intrare(pentru citirea datelor)
fluxuri de ieșire(pentru scrierea datelor)
După tipul de date pe care operează
fluxuri de octeți(comunicarea serială se realizează pe 8 biți)
fluxuri de caractere(comunicarea serială se realizează pe 16 biți)
După acțiunea lor:
fluxuri primare de citire/scriere a datelor(se ocupă efectiv cu citirea/scrierea
datelor)
fluxuri pentru procesarea datelor
Fluxurile de octeți și fluxurile de caractere
Pentru a putea face o diferență între aceste două tipuri amintim care sunt fișierele text și
fișierele binare.
Un fișier care poate fi procesat folosind un editor de text, este un fișier text. Toate
celelalte fișiere sunt numite binare. Acestea nu pot fi editate cu un editor de text și sunt
create pentru a fi cititte de programe anumite.
De exemplu , fișierul sursă *.java este stocat într-un fișier text care poate fi citit cu orice
editor de text, iar fișierul *.class este stocat într-un fișier binar care este citit de JVM.
Calculatoarele nu fac diferență între cele două tipuri de fișiere. Toate fișierele sunt
stocate în format binar.
Fluxurile de octeți și fluxurile de caractere
Fluxurile I/O binare(la nivel de octeți ) nu necesită conversii de cod. Dacă vom
scrie o valoare numerică folosind fluxuri binare valoare exactă din memorie va fi
transferată în fișier.
Fluxurile de octeți și fluxurile de caractere
Fluxurile de octeți și fluxurile de caractere
În general , trebuie să folosim fluxuri I/O bazate pe caractere atunci cînd lucrăm cu
fișiere create de editoare text și fluxuri I/O binare pentru lucrul cu fișierele binare create
de JVM.
Clasele și interfețele standard pentru lucrul cu fluxuri se găsesc în pachetul java.io. Deci
orice program care necesită operații de intrare sau ieșire trebuie să conțină instrucțiunea
de import a pachetului java.io.
Fluxurile de octeți
Fluxurile Java Byte sunt utilizate pentru a efectua intrarea și ieșirea de
octeți pe 8 biți .
Deși există multe clase legate de fluxurile de caractere, clasele cele mai
frecvent utilizate sunt FileInputStream și FileOutputStream.
Cei mai utilizați constructori sunt cei care primesc ca argument numele
fișierului . Aceștia pot provoca excepții de tipul FileNotFoundException
în cazul în care fișierul cu numele specificat nu există.
Din acest motiv orice creare a unui flux de acest tip trebuie făcută într-un
bloc try-catch sau metoda în care sunt create fluxurile respective trebuie
să arunce excepțiile de tipul FileNotFoundException sau de tipul
superclasei IOException
declararea excepției în metodă folosind bloc try-catch
public static void main(String []args) public static void main(String []args){
throws IOException{ try{
//operațiile intrare/ieșire //operațiile intrare/ieșire
}catch(IOException ex){...}
}
Fluxurile de octeți
Exemplu: Programul ca copia conținutul fișierului in.txt într-un alt fișier out.txt. Ambele
fișiere se află în directoriul curent.
import java.io.*;
public class CopieFisier {
public static void main(String args[]) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
Fluxurile de caractere
Clasele care asigură acest lucru , cel mai des utilizate sunt FileReader and
FileWriter .
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}}}
Ierarhia claselor care operează cu fluxurile I/O
Fluxuri Standard(Standard Stream)
În Java sunt create automat 3 fluxuri pentru utilizatori:
System.out(ex. System.out.println(“mesaj”);)
System.in (ex.int i=System.in.read() ;)
System.err(ex. System.err.println(“error mesage”);)
Toate aceste fluxuri sunt atașate de consolă
Ce este serializarea obiectelor?
În mod normal orice obiect creat în Java este distrus atunci cînd finisează
programul care l-a creat, sau atunci cînd nu mai este referință la obiect acesta
este distrus automat de procesul de colectare(Garbage Collector).
Sunt multe situații în care datele cu care lucrează un program trebuie să aibă o
durată de viață mai mare decît a programului care le-a creat- trebuie să
supravețuiască în afara spațiului de adrese a unei JVM.
Pentru a putea serializa starea unui obiect este necesar ca clasa acestuia să
implementeze interfața Serializable folosind clasele de serializare și fluxurile de
ieșire la nivel de octeți ,vom converti într-o secvență de octeți starea obiectului și
o vom salva fie într-un fișier , fie într-o bază de date sau memorie.
În ce constă procesul de deserializare?
Presupunem că avem deja un obiect serializat anterior, salvat într-un fișier sau
BD sau memorie, pentru a deserializa obiectul respectiv vom folosi clasele de
deserializare și fluxurile de intrare la nivel de octeți care reconstruiesc obiectul
original.
file.close();
}}
Deserializare
class TestDeserializareAngajat{
public static void main(String [] args){
try {
FileInputStream file=new FileInputStream("out.ser"); ObjectInputStream st= new ObjectInputStream(file); Angajat
persoana=(Angajat)st.readObject(); st.close();
file.close();
System.out.println("Numele angajatului:"+persoana.getNume()); System.out.println("Virsta angajatului :"+persoana.getAni());
}catch (IOException ex){ ex.printStackTrace();
} catch (ClassNotFoundException e) {e.printStackTrace();}}}
Dezavantajul mecanismului implicit de serializare este că algoritmul pe care se
bazează , fiind mai mult creat pentru cazul general , se comportă ineficient în
anumite situații concrete: poate fi mult mai lent decît este cazul sau reprezentarea
binară generată pentru un obiect poate fi mult mai voluminoasă decît ar trebui.
Notă: În corpul metodei writeObject() pentru a controla datele ce vor fi supuse serializării
se vor folosi metode ca stream.writeInt(...), stream.writeDouble(...) ,... .Analogic și în
corpul metodei readObject() se vor folosi metode de tip stream.readInt(...), etc
Atunci cînd dorim un control mai amănunțit al serializării vom implementa interfața Externalizable(extinde
interfața Serializable) și oferă un control complet al formatului extern al obiectului.
Dacă obiectul serializat conține referințe la alte obiecte, acestea sunt și ele serializate
automat urmînd aceleași reguli.
De ce este utilă serializarea?
Asigură un mecanism simplu și rapid de utilizat pentru salvarea și restaurarea datelor.
Asigură persistența obiectelor , adică obiectul poate exista și între apelurile
programelor care îl folosesc, nu doar în momentul execuției programului care l-a creat.
Acest lucru se realizează prin serializarea obiectului și scrierea lui pe disc înainte de
terminarea unui program , apoi, la relansarea programului , obiectul va fi citit de pe
disc și starea lui refăcută.
Compensarea diferențelor între sisteme de operare- transmiterea unor informații între
platforme de lucru diferite se realizează unitar, independent de formatul de
reprezentare a datelor.
Transmiterea datelor în rețea - Aplicațiile ce rulează în rețea pot comunica între ele
folosind fluxuri pe care sunt trimise , respectiv recepționate obiecte serializate.
La general serializarea se folosește atunci cînd avem nevoie ca datele
încapsulate într-o instanță a unei clase să poată exista înafara timpului de
execuție a unei mașini virtuale.