Fluxuri de date
Un flux de date (stream) reprezinta un canal de comunicatii prin care datele circula de la o sursa catre o destinatie. In limbajul Java, fluxurile si operatiile corespunzatoare sunt implementate prin intermediul claselor din pachetul java.io. Orice program care utilizeaza operatii de intrare/iesire trebuie sa contina instructiunea import pentru pachetul java.io.
import java.io.*.
Pentru lucrul cu fluxuri de date sunt necesari urmatorii pasi: deschidere flux, citire/scriere date, inchidere flux dupa utilizare. Este recomandata inchiderea fluxurilor de date neutilizate pentru a elibera resursele ocupate de catre acestea. Pentru a inchide un flux de date este utilizata metoda close().
Operatiile de intrare/iesire pot introduce exceptii de tipul IOException. Din aceasta clasa de exceptii standard sunt derivate o serie de exceptii specializate:
• EOFException este generata la intalnirea sfarsitului unui fisier;
• FileNotFoundException este generata la incercarea de deschidere a unui fisier inexistent;
• MalformedURLException este generata la accesarea unei adrese web invalide;
• InterruptedIOException este generata la intreruperea unei operatii de intrare/iesire, in timpul executiei.
Clasificarea fluxurilor de date
Un flux care citeste date de la o sursa poarta denumirea de flux de intrare (Input Stream), in timp ce un flux care scrie date la o destinatie poarta numele de flux de iesire (Output Stream). Clasificarea fluxurilor in fluxuri de intrare si fluxuri de iesire are in vedere directia canalului de comunicatie.
Din punctul de vedere al tipului de date pe care opereaza, fluxurile pot fi clasificate in fluxuri de octeti (mod binar) si fluxuri de caractere (mod text).
Clasele de baza pentru ierarhia claselor care se ocupa cu fluxurile de octeti sunt InputStream (pentru fluxurile de intrare), respectiv OutputStream (pentru fluxurile de iesire). Acestea sunt clase abstracte din care sunt derivate clase care implementeaza fluxurile specializate pentru citirea/scrierea datelor pe 8 biti. Clasele derivate au denumiri care contin terminatia InputStream, respectiv OutputStream.
Clasele abstracte InputStream, respectiv OutputStream definesc metode de baza pentru citirea, respectiv scrierea datelor:
• int read();
• int read(byte buf[]);
• int write();
• int write(byte buf[]).
InputStream FileInputStream FilterInputStream BufferedInputStream DataInputStream LineNumberInputSteam PushbackInputStream PipedInputStream SequenceInputStream ByteArrayInputStream StringBufferInputStream ObjectInputStream OutputStream FileOutputStream FilterOutputStream BufferedOutputStream DataOutputStream PrintStream PipedOutputStream ByteArrayOutputStream OnjectOutputStream
package ro.virtualcampus.copy; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
public class ByteStream { | |
public static void main(String[] args) { | |
FileInputStream fin = null; | |
FileOutputStream fout = null; | |
try { | |
fin = new FileInputStream("in.png"); | |
fout = new FileOutputStream("out.png"); | |
int c; | |
while ((c = fin.read()) != -1) { | |
fout.write((byte)c); | |
} | |
System.out.println("proces finalizat cu succes"); | |
} catch (FileNotFoundException e) { | |
System.out.println("fisier inexistent"); | |
e.printStackTrace(); | |
} catch (IOException e) { | |
System.out.println("eroare citire"); | |
e.printStackTrace(); | |
} finally { | |
try { | |
if (fin != null) | |
fin.close(); | |
if (fout != null) | |
fout.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} |
Clasele de baza pentru ierarhia claselor care se ocupa cu fluxurile de caractere sunt Reader (pentru fluxurile de intrare), respectiv Writer (pentru fluxurile de iesire). Acestea sunt clase abstracte din care sunt derivate clase care implementeaza fluxurile specializate pentru citirea/scrierea datelor pe 16 biti. Clasele derivate au denumiri care contin terminatia Reader, respectiv Writer.
In mod similar claselor abstracte precedente, clasele abstracte Reader, respectiv Writer definesc metode de baza pentru citirea, respectiv scrierea datelor:
• int read();
• int read(char buf[]);
• int write();
• int write(char buf[]).
Reader InputStreamReader FileReader BufferedReader LineNumberReader FilterReader PushbackReader CharArrayReader PipedReader StringReader Writer OutputStreamWriter FileWriter BufferedWriter FilterWriter CharArrayWriter PipedWriter StringWriter
package ro.virtualcampus.copy; | |
import java.io.FileReader; | |
import java.io.FileWriter; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
public class CharStream { | |
public static void main(String[] args) { | |
FileReader fin = null; | |
FileWriter fout = null; | |
try { | |
fin = new FileReader("in.txt"); | |
fout = new FileWriter("out.txt"); | |
int c; | |
while ((c = fin.read()) != -1) { | |
fout.write((char) c); | |
} | |
System.out.println("proces finalizat cu succes"); | |
} catch (FileNotFoundException e) { | |
System.out.println("fisier inexistent"); | |
e.printStackTrace(); | |
} catch (IOException e) { | |
System.out.println("eroare citire"); | |
e.printStackTrace(); | |
} finally { | |
try { | |
if (fin != null) | |
fin.close(); | |
if (fout != null) | |
fout.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} |
O alta clasificare a fluxurilor are in vedere actiunea fluxului de date. Din acest punct de vedere vorbim despre fluxuri primare si fluxuri de procesare. Fluxurile primare sunt responsabile cu citirea/scrierea efectiva a datelor, punand la dispozitie implementari ale metodelor de baza read(), respectiv write(). Din aceasta categorie fac parte implementari precum: FileReader, FileWriter, FileInputStream, FileOutputStream.
Fluxuri de procesare sunt responsabile cu preluarea datelor de la un flux primar si procesarea acestora pentru a le oferi intr-o forma mai utila. Introduc un buffer in procesul de citire/scriere a datelor si reduc numarul de accesari la dispozitivul ce reprezinta sursa/destinatia originala a datelor. Exemple de clase care fac parte din categoria fluxurilor de procesare includ: BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream.
Nu pot exista de sine statatoare, ci se suprapun pe un flux primar de citire/scriere a datelor. Constructorii claselor pentru fluxurile de procesare nu primesc ca argument un dispozitiv extern de memorare a datelor, ci o referinta la un flux primar responsabil cu citirea/scrierea efectiva a datelor.
BufferedReader in = new BufferedReader(new FileReader("fisier.txt"));
FileReader filein = new FileReader("fisier.txt"); BufferedReader in = new BufferedReader(filein);
Fluxuri standard de intrare/iesire
Pentru lucrul cu fluxuri de date pot fi utilizate diverse dispozitive. Totusi, exista doua astfel de dispozitive care se intalnesc in orice configuratie de calculator, motiv pentru care poarta numele de dispozitive standard pentru intrare (tastatura), respectiv iesire (monitor).
Fluxurile de intare/iesire standard sunt disponibile implicit in orice aplicatie Java si apar sub forma de campuri statice ale clasei System. Fluxurile de intrare/iesire corespunzatoare dispozitivelor standard nu se inchid prin intermediul metodei close().
public final class System { | |
... | |
/** | |
* The "standard" input stream. This stream is already | |
* open and ready to supply input data. Typically this stream | |
* corresponds to keyboard input or another input source specified by | |
* the host environment or user. | |
*/ | |
public static final InputStream in = null; | |
... | |
/** | |
* The "standard" output stream. This stream is already | |
* open and ready to accept output data. Typically this stream | |
* corresponds to display output or another output destination | |
* specified by the host environment or user. | |
*/ | |
public static final PrintStream out = null; | |
... | |
} |
Clasa ReadIn permite citirea unui caracter de la tastatura si afisarea la consola a caracterului si a codului ASCII corespunzator acestuia.
package ro.virtualcampus.read; | |
import java.io.IOException; | |
public class ReadIn { | |
public static void main(String args[]) { | |
char c; | |
System.out.print("introduceti un caracter: "); | |
try { | |
c = (char) System.in.read(); | |
System.out.println("ati introdus caracterul " + c); | |
System.out.println("cod ASCII caracter " + (int) c); | |
} catch (IOException e) { | |
System.out.println("eroare citire"); | |
e.printStackTrace(); | |
} | |
} | |
} |
introduceti un caracter: a ati introdus caracterul a cod ASCII caracter 97
Utilizarea fluxurilor de date
package ro.virtualcampus.read; | |
import java.io.*; | |
public class ReadFromFile { | |
public static void main(String args[]) { | |
BufferedReader fin = null; | |
try { | |
fin = new BufferedReader(new FileReader("in.txt")); | |
String buffer; | |
while ((buffer = fin.readLine()) != null) { | |
System.out.println(buffer); | |
} | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} finally { | |
try { | |
if (fin != null) | |
fin.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} |