fluxuri in java

15
Fluxuri Dennis Ritchie implementeaza in 1984 primul sistem I/O pe baza de stream in cadrul sistemului de operare Unix. Acest concept are la baza crearea unui canal de comunicatie intre doua entitati: sursa si destinatia. Sursa scrie informatii in canalul de comunicatie, iar destinatia poata sa citeasca aceste date, canalul permitand trecerea fluxului de date intr-o singura directie. Fluxurile pot fi clasificate după "direcţia" canalului de comunicaţie : fluxuri de intrare (pentru citirea datelor) fluxuri de iesire (pentru scrierea datelor) după tipul de date pe care operează: fluxuri de octeţi (transfer serial pe 8 biţi) fluxuri de caractere (transfer serial pe 16 biţi) sau după acţiunea lor: fluxuri primare de citire/scriere a datelor fluxuri pentru procesarea datelor Datorita faptului ca exista doua directii de comunicare, exista doua tipuri mari de streamuri pentru orice nod de comunicatie: input stream si output stream. Tastatura ar fi un exemplu de input stream, iar monitorul un output stream. Sursa si destinatia nu trebuie sa fie neaparat periferice, ele pot fi si module soft. Flux de intrare (input stream) Flux de iesiree (output stream) Clasele care descriu operaţiile de intrare-ieşire se află în pachetul java.io. Acesta conţine două categorii de fluxuri: fluxuri la nivel de octet (introduse din versiunea JDK 1.0.2) şi fluxuri la nivel de caracter (introduse începând cu versiunea JDK 1.1) care in Java au 2 octeti.

Upload: alex9216

Post on 09-Sep-2015

2 views

Category:

Documents


0 download

DESCRIPTION

Dennis Ritchie implementeaza in 1984 primul sistem I/O pe baza de stream in cadrul sistemului de operare Unix. Acest concept are la baza crearea unui canal de comunicatie intre doua entitati: sursa si destinatia. Sursa scrie informatii in canalul de comunicatie, iar destinatia poata sa citeasca aceste date, canalul permitand trecerea fluxului de date intr-o singura directie.

TRANSCRIPT

  • Fluxuri

    Dennis Ritchie implementeaza in 1984 primul sistem I/O pe baza de stream in cadrul sistemului de operare Unix. Acest concept are la baza crearea unui canal de comunicatie intre doua entitati: sursa si destinatia. Sursa scrie informatii in canalul de comunicatie, iar destinatia poata sa citeasca aceste date, canalul permitand trecerea fluxului de date intr-o singura directie.

    Fluxurile pot fi clasificate dup "direcia" canalului de comunicaie : fluxuri de intrare (pentru citirea datelor)

    fluxuri de iesire (pentru scrierea datelor)

    dup tipul de date pe care opereaz: fluxuri de octei (transfer serial pe 8 bii) fluxuri de caractere (transfer serial pe 16 bii)

    sau dup aciunea lor: fluxuri primare de citire/scriere a datelor

    fluxuri pentru procesarea datelor

    Datorita faptului ca exista doua directii de comunicare, exista doua tipuri mari de streamuri

    pentru orice nod de comunicatie: input stream si output stream. Tastatura ar fi un exemplu de

    input stream, iar monitorul un output stream. Sursa si destinatia nu trebuie sa fie neaparat

    periferice, ele pot fi si module soft.

    Flux de intrare (input stream)

    Flux de iesiree (output stream)

    Clasele care descriu operaiile de intrare-ieire se afl n pachetul java.io.

    Acesta conine dou categorii de fluxuri: fluxuri la nivel de octet (introduse din versiunea JDK 1.0.2) i fluxuri la nivel de caracter (introduse ncepnd cu versiunea JDK 1.1) care in Java au 2 octeti.

  • Fluxurile la nivel de octet utilizeaza doua ierarhii avnd drept clase radacina clasele InputStream si OutputStream ) iar din ratiuni de implementare a conceptului de Internationalization s-a dezvoltat o solutie alternativa care este orientata pe 16 biti (unicode) utilizand alte doua ierarhii avnd drept clase radacina clasele Reader si Writer.

    InputStream/OutputStream

    Sunt clase abstracte care definesc functionalitatile de baza pentru citirea respectiv scrierea

    unui bloc de octeti. Toate celelalte tipuri de streamuri pentru octeti se deriva din aceste

    doua.

    DataInputStream/DataOutputStream

    Sunt clase de tip filtre care se pun peste clasele InputStream/OutputStream si permit

    citirea/scrierea a diferitelor tipuri de date (logice, intregi, reale, siruri de caractere,...)

    ObjectInputStream/ObjectOutputStream

    Se utilizeaza pentru scrierea obiectelor serializabile respectiv reconstructia lor dupa citire.

    BufferedInputStream/BufferedOutputStream

    Clase care realizeaza operatiile de citire scriere cu zone tampon pentru a mari eficienta

    acestor operatii.

    PipedInputStream/PipedOutputStream

    Clase pentru realizarea mecanismului conducta (pipe).

    FileInputStream/FileOutputStream

    Clase care ofera facilitati pentru accesul fisierelor din sistemul local de fisiere

  • Reader/Writer

    Sunt clase abstracte care definesc functionalitatile de baza pentru citirea respectiv scrierea

    unui bloc de caractere.

    InputStreamReader/OutputStreamWriter

    Sunt clase utilizate pentru conversia blocurilor de caractere la blocuri de octeti.

    BufferedReader/BufferedWriter

    Clase care realizeaza operatiile de citire scriere cu zone tampon pentru a mari eficienta

    acestor operatii.

    PrintWriter

    Un stream special de caractere care permite scrierea textelor. System.out este de acest tip.

    PipedReader/PipedWriter

    Clase pentru realizarea mecanismului conducta (pipe).

    FileReader/FileWriter

    Clase care ofera facilitati pentru accesul fisierelor din sistemul local de fisiere.

  • Fluxurile sunt unidirectionale: datele circula numai de la procesul producator la procesul consumator. Fiecare flux are un singur proces producator si un singur proces consumator.

    Consumatorul si producatorul nu comunica direct prin interfata de flux. Procesul producator genereaza un flux de date care este transmis codului Java de tratare a fluxurilor. De aici datele sunt trimise procesului consumator. Producatorul si consumatorul nu stiu nimic unul despre celalalt.

    Un avantaj al streamurilor este posibilitatea conectarii acestora, obtinand un mecanism pipe-line

    de comunicare interprocese.

    Fluxuri standard de intrare/ieire

    Limbajul Java pune la dispozitia utilizatorului trei fluxuri standard pentru comunicare cu consola: Fluxul standard de intrare (Standard Input) folosit pentru citirea datelor. Fluxul standard de ieire (Standard Output) folosit pentru afiarea datelor. Fluxul standard de eroare (Standard Error) folosit pentru afiarea erorilor.

    In consecinta clasa System din pachetul java.lang contine trei referinte statice de urmatoarele tipuri:

    InputStream in PrintWriter out PrintWriter err

    Astfel, pentru Standard Input exist fluxul System.in, pentru Standard Output, System.out iar pentru Standard Error, System.err

    Aceste trei streamuri nu trebuie deschise, ele se deschid automat inaintea executiei aplicatiei. Celelalte streamuri se deschid in momentul crearii lor prin apelul constructorului clasei corespunzatoare. Streamurile in, out si err nu trebuie inchise; celelalte streamuri inchizandu-se cu apelul metodei close().

    Cei trei membrii in, out, err ai clasei System sunt membri statici, ceea ce face posibil accesul lor

    prin utilizarea direct a numelui clasei, fr a fi nevoie de instanierea unui obiect.

    Citirea si scrierea din si in aceste streamuri se realizeaza cu ajutorul metodelor read() si write()

    care au mai multe forme supraincarcate. In cazul streamurilor de octeti metoda read() are

    urmatoarele trei forme:

    int read() throws IOException; int read( byte b[])throws IOException; int read( byte b[], int offset, int length ) throws IOException;

    Prima forma citeste un octet dar returneaza rezultatul sub forma unui intreg. In caz de eroare se

    genereaza exceptia IOException, deci orice apel de metoda read obligatoriu trebuie inclus intr-un

    context de tratarea exceptiilor. La sfarsitul fluxului read() returneaza -1.

    try{ int val = System.in.read(); ... } catch (IOException e ){ // Tratarea exceptiei }

  • Prin a doua si a treia forma se pot citi deodata un bloc intreg de octeti. Octetii cititi vor fi stocati

    intr-un tablou de octeti primit ca parametru. Aceste doua metode returneaza numarul octetilor

    efectiv cititi.

    byte b[1024]; try{ int bytesread=System.in.read( b ); } catch( IOException e ){...}

    Clasa InputStream defineste si o metoda available() care returneaza numarul octetiilor

    disponibili din flux.

    try{ int disponibili = System.in.available(); if( disponibili > 0){ byte b[] = new byte[ disponibili ]; System.in.read( b ); } } catch( IOException e ){ ... }

    Functia skip(int) se utilizeaza pentru a muta pozitia citirii peste un numar de octeti specificat prin parametru. Toate metodele de citire blocheaza firul de executie care doreste sa faca operatiile I/O pana cand toate datele sunt disponibile, s-a ajuns la sfarsitul fluxului de date sau a aparut o exceptie.

    Metodele mark() si reset() se folosesc impreuna oferind posibilitatea reluarii citirii din

    stream. Prin metoda mark(int readLimit) se memoreaza pozitia curenta in stream si se creaza

    o zona tampon de dimensiunea specificata prin readLimit. Prin reset() se repozitioneaza

    indicatorul in stream la pozitia marcata prin mark(). Aceste doua metode pot fi folosite doar in

    cazul in care streamul suporta marcare. Verificarea acestui lucru se poate face prin

    markSupported().

    Exemple

    copiaza intrarea standard la iesirea standard.

    un meniu cu optiuni : data curenta, proprietati sistem

    afiseaza la consola continutul unei pagini web

    aduna 2 numere citite de la consola

    citirea unui sir de caractere utilizand BufferedReader

  • //

    // copiaza intrarea standard la iesirea standard

    // pana la CTRL-Z

    //

    import java.io.*;

    public class Copiere{

    public static void copiere (InputStream sin, OutputStream sout)

    throws IOException{

    int b;

    while(( b=sin.read()) != -1) sout.write(b);

    sout.flush();

    }

    public static void main( String args[]){

    try{

    copiere(System.in, System.out );

    }

    catch( IOException e ){

    System.out.println("Eroare de copiere");

    }

    }

    }

  • //Utilizare stream-uri standard

    //Acestea sunt asociate implicit cu echpamentele periferice

    //Tastatura Sistem.in

    //Ecranul monitorului Sistem.out / Sistem.err

    import java.io.*;

    import java.util.*;

    public class IODemo{

    public static void main(String[] s){

    boolean exit=false;

    System.out.println(" Informatii despre sistem\n");

    while(!exit){

    System.out.println("Optiuni....");

    System.out.println("\t (D) Data");

    System.out.println("\t (P) Proprieteti sistem");

    System.out.println("\t (T) Terminare");

    try

    {

    char readChar=(char)System.in.read();

    int avlb=System.in.available();

    System.in.skip(avlb);

    switch(readChar)

    {

    case 'D':

    case 'd': System.out.println("Data:"+

    new Date().toString());

    break;

    case 'P':

    case 'p': Properties prop=System.getProperties();

    prop.list(System.out);

    break;

    case 'T':

    case 't': System.out.println("La revedere...");

    exit=true;

    break;

    }

    }

    catch(IOException e)

    {

    System.err.println(e.getMessage());

    }

    }

    }

    }

  • // afiseaza la consola continutul unei pagini web

    //

    import java.net.*;

    import java.io.*;

    class StreamURL {

    public static void main(String[] args){

    String rawdata;

    try{

    // Construct a URL object

    URL url = new URL("http://193.231.17.40/index.html");

    // Open a connection to the URL object

    BufferedReader html =

    new BufferedReader(new

    InputStreamReader(url.openStream()));

    //Read and display the HTML file one line at a time.

    while((rawdata = html.readLine()) != null)

    System.out.println(rawdata);

    }

    catch(UnknownHostException e){ System.out.println(e); }

    catch(MalformedURLException e){ System.out.println(e); }

    catch(IOException e){ System.out.println(e); }

    }

    }

  • // aduna 2 numere citite de la consola

    import java.io.BufferedReader;

    import java.io.InputStreamReader;

    public class Adunare {

    public static void main(String args[]){

    int a=0,b=0;

    BufferedReader input = new BufferedReader(new

    InputStreamReader(System.in));

    try {

    String inputLine = input.readLine();

    a = Integer.parseInt(inputLine);

    b = Integer.parseInt(input.readLine());

    } catch (java.io.IOException e) {

    System.out.println("oops! An input error");

    }

    finally{

    System.out.println(a + "+" + b +" = "+ (a+b));

    }

    }

    }

  • // citirea unui sir de caractere utilizand BufferedReader

    import java.io.*;

    class BRReadLines {

    public static void main(String args[]) throws IOException

    {

    // create a BufferedReader using System.in

    BufferedReader br = new BufferedReader(new

    InputStreamReader(System.in));

    String str;

    System.out.println("Enter lines of text.");

    System.out.println("Enter 'stop' to quit.");

    do {

    str = br.readLine();

    System.out.println(str);

    } while(!str.equals("stop"));

    }

    }

  • Clasa File

    Clasa File contine informatii despre fisiere si directoare si defineste o serie de metode pentru a obtine respectiv a modifica aceste informatii. Principalele metode sunt urmatoarele:

    Metoda Tipul returnat Descriere

    canRead() boolean Are permisiunea de citire?

    canWrite() boolean Are permisiunea de scriere?

    delete() boolean Stergere

    exists() boolean Exista fisierul?

    getAbsolutePath() String Calea completa spre fisier

    getCanonicalPath() String Calea completa spre fisier

    getName() String Numele fisierului

    getParent() String Numele catalogului parinte

    getPath() String Calea spre fisier

    isAbsolute() boolean Este un nume absolut?

    isDirectory() boolean Este un director?

    isFile() boolean Este un fisier ordinar?

    lastModified() long Data ultimei modificari

    length() long Lungimea fisierului

    list() String[] Lista fisierelor din director

    mkdir() booolean Crearea de director

    mkdirs() boolean Crearea tuturor directoarelor

    Exemple

    scrie intr-un fisier continutul altui fisier

    afiseaza la consola continutul unui fisier text

    listeaza continutul unui argument dat in linia de comanda (nume de director sau fisier)

  • // scrie intr-un fisier continutul altui fisier

    import java.io.*;

    public class Copy {

    public static void main(String[] args) throws IOException {

    FileReader in = new FileReader("in.txt");

    FileWriter out = new FileWriter("out.txt");

    int c;

    while ((c = in.read()) != -1)

    out.write(c);

    in.close();

    out.close();

    }

    }

    /*

    * Display a text file.

    * To use this program, specify the name of the file that you want

    * to see. For example, to see a file called TEST.TXT use:

    java ShowFile TEST.TXT

    */

    import java.io.*;

    class ShowFile {

    public static void main(String args[]) throws IOException

    {

    int i;

    FileInputStream fin;

    try {

    fin = new FileInputStream(args[0]);

    } catch(FileNotFoundException e) {

    System.out.println("File Not Found");

    return;

    } catch(ArrayIndexOutOfBoundsException e) {

    System.out.println("Usage: ShowFile File");

    return;

    }

    // read characters until EOF is encountered

    do {

    i = fin.read();

    if(i != -1) System.out.print((char) i);

    } while(i != -1);

    fin.close();

    }

    }

  • // Programul urmator primeste de la linia de comanda un nume.

    // Daca numele reprezinta numele unui director atunci se listeaza continutul

    acestuia, altfel daca este fisier, atunci se afiseaza fisierul pe terminal..

    import java.io.*;

    public class Listare {

    public static void main( String args[] ) {

    File file;

    if( args.length != 1 ){

    System.out.println("Utilizare: java Listare ");

    return;

    }

    try{

    file = new File( args[0]);

    }

    catch( Exception e ){

    System.out.println(" Fisier inexistent ");

    return;

    }

    if( ! file.exists() || !file.canRead() ){

    System.out.println("Eroare de citire fisier: "+ args[0]);

    return;

    }

    if( file.isDirectory() ){

    String files[] = file.list();

    for( int i =0; i

  • Clasa RandomAccessFile Aceasta clasa implementeaza interfetele DataInput si DataOutput, permitand citirea si scrierea datelor primitive Java. Clasa permite accesul direct al fisierului. Clasele cu care am lucrat pana acum au permis doar accesul secvential. Crearea unui obiect de tip RandomAccessFile se face in modul urmator:

    try{ RandomaccessFile file = new randomAccessFile("unfisier","rw"); ... } catch( IOException e){ }

    Primul parametru al constructorului poate fi un sir de caractere care reprezinta calea si numele fisierului sau un obiect de tip File, iar al doilea parametru reprezinta modul de access ( r-citire, w-scriere). Si aceasta clasa defineste metode de citire si scriere, dar pe langa aceste metode contine si una care permite accesul direct: seek( long pozitie).

    Exemple

    Se creaza un fisier cu valori de tip double generate aleator si se afiseaza fisierul pe terminal. Dupa aceea se modifica continutul aleator, modificand doar cateva elemente si se afiseaza inca o data fisierul pe terminal.

  • import java.io.*;

    import java.util.*;

    public class FisierAccesDirect{

    RandomAccessFile f;

    String name;

    long dim;

    public FisierAccesDirect( String name, long dim ) throws IOException

    {

    this.name = name;

    this.dim = dim;

    f = new RandomAccessFile( name, "rw");

    Random r = new Random( 10000 );

    for( int i=0; i< dim; i++ ) {

    double d = r.nextDouble();

    f.writeDouble( d );

    System.out.print( d+"\t");

    }

    f.close();

    f = new RandomAccessFile( name, "rw");

    }

    public double getDouble( long poz ) throws IOException {

    f.seek( poz * 8 );

    return( f.readDouble());

    }

    public void putDouble( long poz, double d ) throws IOException {

    f.seek( poz * 8);

    f.writeDouble( d );

    }

    public long getDim() { return dim; }

    public static void main( String args[] ) {

    try {

    FisierAccesDirect c = new FisierAccesDirect("doublefile",10);

    Random r = new Random();

    long n = c.getDim();

    long i;

    System.out.println("Dimension : "+n);

    for( i=0; i