Documente online.
Username / Parola inexistente
  Zona de administrare documente. Fisierele tale  
Am uitat parola x Creaza cont nou
  Home Exploreaza
Upload




























Fluxuri de intrare/iesire

Informatica




Fluxuri de intrare/iesire

Clasele ce ofera facilitati de intrare/iesire se gasesc în pachetul java.io




Schema generala

Una dintre metodele prin care putem îmbogati functionalitatea unei clase C este cea de a declara în ea un câmp d de tipul altei clase D si de a initializa acest câmp printr-un constructor:

class C

. . .

În acest mod, în metodele clasei C putem invoca metode ale clasei D, prin intermediul obiectului d.

În cazul în care clasa D extinde clasa C, aceasta tehnica poarta numele de suprapunerea de obiecte, care aplicata la fluxuri de intrare/iesire se numeste suprapunere de fluxuri. În aceasta situatie sintagma "suprapunerea obiectelor adauga noi facilitati (functionalitati)", înseamna adaptarea metodelor clasei suprapuse la contextul clasei care o suprapune.

Facilitatile de intrare/iesire din Java au la baza notiunea de flux. Un flux este o succesiune de elemente (octeti sau caractere), citite si scrise secvential.

Pentru un flux de intrare sursa datelor poate fi un fisier, dar si un sir sau tablou de octeti, respectiv caractere. Pentru un flux de iesire, datele transmise sunt stocate într-un fisier sau într-un tablou de octeti, respectiv caractere. Este posibila (si chiar recomandata) utilizarea zonelor tampon. De asemenea este posibil ca un flux de iesire sa "comunice" cu un flux de intrare, în sensul ca datele scrise în fluxul de iesire vor constitui sursa pentru fluxul de intrare.

Daca la citire nu sunt înca date disponibile în flux si nu s-a detectat sfârsitul fluxului, atunci firul de executare care realizeaza citirea va fi blocat pâna când vor exista date disponibile. Analog, în cazul a doua fluxuri comunicante ce folosesc o zona tampon, firul de executare care are sarcina sa scrie va fi blocat în situatia în care zona tampon este plina.

O prima clasificare a fluxurilor are în vedere elementele de baza care sunt transmise: caractere sau octeti.

Object

InputStream (clasa abstracta pt. citire la nivel de octet)

OutputStream (clasa abstracta pt. scriere la nivel de octet)

Reader (clasa abstracta pt. citire la nivel de caracter)

Writer (clasa abstracta pt. scriere la nivel de caracter)

 


Toate clasele, interfetele si metodele din pachetul java.io au modificatorul public, iar în plus aproape toate metodele contin clauza throws IOException

Fluxuri ce lucreaza la nivel de octet

O structura simplificata de clase

Object

DataInput (interfata)

InputStream (abstracta)

FileInputStream

FilterInputStream

DataInputStream implements DataInput

DataOutput (interfata)

OuputStream (abstracta)

FileOutputStream

FilterOutputStream

DataOutputStream implements DataOutput

 


Clasele neabstracte, afara de FileInputStream si de FileOutputStream, au un constructor cu un parametru de tipul InputStream, respectiv de tipul OutputStream

Exemplul 1. Într-o prima etapa vom citi de la intrarea standard un numar natural n si apoi n numere reale; vom crea în directorul curent un fisier cu numele out.dat în care vom scrie datele citite. Într-o a doua etapa vom citi din fisierul out.dat valoarea n si cele n numere si le vom tipari la iesirea standard.

Prima etapa este realizata de urmatorul program:

import java.io.*;

class Unu

unde:

- prin new FileOutputStream("out.dat") este creat fisierul out.dat

- obiectul g de tipul DataOutputStream foloseste metodele writeInt si writeDouble (anuntate în interfata DataOutput si implementate în clasa DataOutputStream) pentru a scrie în fisierul out.dat

- pentru închiderea fisierului este invocata metoda close a clasei FilterInputStream (mostenita din DataOutputStream

A doua etapa este realizata de urmatorul program:

import java.io.*;

class Doi

unde:

- prin new FileInputStream("out.dat") este deschis fisierul out.dat

- obiectul g de tipul DataInputStream foloseste metodele readInt si readDouble (anuntate în interfata DataInput si implementate în clasa DataInputStream) pentru a citi din fisierul out.dat

- pentru închiderea fisierului este invocata metoda close a clasei FilterInputStream (mostenita din DataInputStream

. Interfata DataOutput

Contine metode menite a scrie, într-un flux de iesire neprecizat, date de tipuri primitive, precum si siruri de caractere.



void write(int b)

void writeBytes(String s) throws NullPointerException

void writeChars(String s) throws NullPointerException

void writeUTF(String s) void writeBoolean(boolean v)

void writeByte(int v) void writeShort(int v)

void writeChar(int v) void writeInt(int v)

void writeLong(long v) void writeFloat(float v)

void writeDouble(double v)

. Interfata DataInput

int skipBytes(int n) boolean readBoolean()

byte readByte() int readUnsignedByte()

short readShort() int readUnsignedShort()

char readChar() int readInt()

long readLong() float readFloat()

double readDouble() String readLine()

String readUTF()

Observatie. Daca s-a ajuns la sfârsitul fluxului de intrare înainte de a se fi citit numarul dorit de octeti, va fi lansata exceptia EOFException

Se presupune ca datele citite au fost scrise în fisier cu metodele complementare anuntate în interfata DataOutput

. Clasa abstracta OutputStream

Adauga:

void flush() void close()

. Clasa abstracta InputStream

Adauga:

long skip(long n) int available() void close()

. Clasele FilterInputStream si FilterOutputStream

class FilterOutputStream extends OutputStream

class FilterInputStream extends InputStream

. Clasele FileOutputStream si FileInputStream

Metodele clasei FileOutputStream implementeaza, respectiv redefinesc metodele cu aceleasi nume si signatura din OutputStream, aplicându-le pentru fluxul de iesire primit ca argument de constructor.

class FileOutputStream extends OutputStream

Constructorul cu un parametru deschide fluxul de iesire nume

class FileInputStream extends InputStream

Constructorul clasei deschide fluxul de intrare constituit de fisierul precizat prin sirul de caractere nume

. Clasele DataOutputStream si DataInputStream

Clasele DataOutputStream si DataInputStream ofera în plus posibilitatea ca fluxurile sa nu mai fie privite la nivel de octet, ci ca succesiunide date primitive sau siruri de caractere. Datele vor fi scrise în fluxul de iesire într-un format independent de modul de reprezentare al datelor în sistemul pe care se lucreaza.

class DataOutputStream extends FilterOutputStream

implements DataOutput

class DataInputStream extends FilterInputStream

implements DataInput

O structura extinsa de clase

Object

DataInput (interfata)

InputStream (clasa abstracta)

FileInputStream

FilterInputStream

DataInputStream

BufferedInputStream

PipedInputStream

DataOutput (interfata)

OutputStream (clasa abstracta)

FileOutputStream

FilterOutputStream

DataOutputStream

Buffered OutputStream

PrintStream

PipedOutputStream

 

Exemplul 2. Adaptam Exemplul 1 la lucrul cu zone tampon, utilizând un buffer pentru fluxul de intrare din clasa Doi. Pentru aceasta este suficient sa înlocuim declararea fluxului g prin:

DataInputStream g = new DataInputStream(

new BufferedInputStream(

new FileInputStream("out.dat") ) );

. Clasele PipedOutputStream si PipedInputStream

Functionalitatea noua oferita de aceste clase consta în crearea a câte un obiect pos, respectiv pis de fiecare din aceste tipuri, obiecte ce sunt "conectate" în urmatorul sens: ceea ce este scris prin intermediul obiectului pos este citit prin intermediul obiectului pis. Fiecare dintre obiecte (fluxuri) cunoaste identitatea celuilalt. Este recomandat sa folosim fire de executare separate pentru utilizarea celor doua obiecte, deoarece încercarea de a realiza acest tip de transmisie din cadrul aceluiasi fir de executare poate conduce la blocare totala. Este folosita o zona tampon cu disciplina de coada. Orice obiect de unul dintre tipurile PipedInputStream si PipedOutputStream trebuie conectat la exact un obiect de celalalt tip, în caz contrar fiind lansata o exceptie.



PipedInputStream extends InputStream

Constructorul cu un parametru creeaza un obiect de tipul PipedInputStream si îl conecteaza la obiectul pos primit ca parametru. Constructorul fara parametri creaza un obiect, dar nu realizeaza conectarea; aceasta trebuie realizata ulterior prin invocarea metodei connect

Câmpul PYPE_SIZE reprezinta marimea cozii de intrare, ale carei elemente apar în buffer. Câmpurile in si out indica pozitiile în care va fi primit urmatorul octet, respectiv pozitia din care va fi citit primul octet din acest flux de intrare. Coada vida este identificata prin in<0, iar coada plina este identificata prin in==out

Prin invocarea metodei receive este primit un octet de intrare.

class PipedOutputStream extends InputStream

Constructorul cu un parametru creeaza un obiect de tipul PipedOutputStream si îl conecteaza la obiectul pis primit ca parametru. Constructorul fara parametri creeaza un obiect, dar nu realizeaza conectarea; aceasta trebuie realizata ulterior prin invocarea metodei connect

Observatie. Daca fluxul de intrare pis si fluxul de iesire pos sunt ambele neconectate, conectarea lor se poate realiza si prin oricare dintre invocarile pis.connect(pos) si pos.connect(pis)

Exemplul 4. Reuam problema Producator - Consumator; sunt transmise valorile din intervalul

class PIS extends PipedInputStream

int OUT()

class Banda

catch (IOException e)

}

synchronized void pune(int b)

IO.write(" P" + b); pos.write(b); notify();

}

catch (IOException e)

catch(InterruptedException e)

}

synchronized int ia()

b = pis.read(); IO.write(" C" + b); notify();

}

catch (IOException e)

catch(InterruptedException e)

return b;

}

class Prod extends Thread

public void run()

catch(InterruptedException e) ;

}

class Cons extends Thread

public void run()

catch(InterruptedException e)

}

while (b<99);

}

class Piped

Clasa Scanner

Clasa Scanner apare în pachetul java.util si permite regasirea într-un text a tipurilor primitive si a sirurilor, folosind expresii regulate.


public final class Scanner extends Object
implements Iterator<String>

Un scanner (obiect de tipul Scanner) împarte intrarea în entitati, folosind un sablon de delimitatori (delimitatorii impliciti sunt spatiile albe) si regaseste entitatile prin invocarea de metode next. Pentru a verifica daca urmeaza o entitate de un anumit tip se folosesc metodele hasNext.

Exemplu. Citirea unui întreg de la intrarea standard se poate realiza astfel:

Scanner sc = new Scanner(System.in);
int i = sc.nextInt();

Intrarea poate fi si un fisier text:

Scanner sc = new Scanner(new File("fisier"));

sau un sir de caractere.

Exemplu. Programul urmator realizeaza citirea repetata de la intrarea standard si introducerea într-un fisier "text" a unei succesiuni de întregi terminata cu o entitate diferita de un întreg, pâna este detectat sirul "STOP".

import java.util.*; import java.io.*;

class Scan

while(!s.equals("STOP"));

out.close();

}

unde despre clasa PrintWriter mentionam doar ca actioneaza la nivel de caracter si pune la dispozitie metodele print si println fara argumente sau cu un argument ce poate fi un tip primitiv sau un sir de caractere.

Metodele de scanare relative la citire pot conduce la blocare prin asteptarea unei valori de intrare.

Metodele next() si hasNext(), precum si metodele asociate tipurilor primitive (ca de exemplu nextInt() si hasNextInt()), încep prin a "sari" peste intrarile ce corespund sabloanelor de intrare si apoi încearca sa regaseascaurmatoarea entitate.

Un obiect de tipul Scanner nu este adecvat lucrului cu fire de executatre decât în prezenta sincronizarii.

Constructorul are un parametru de unul dintre tipurile:

File, InputStream, Readable, String, ReadableByteChannel.

Cele mai folosite metode sunt urmatoarele:

public boolean hasNext()

întoarce true daca mai urmeaza o entitate;

public String next()

detecteaza si întoarce urmatoarea entitate;

public boolean hasNextLine()

întoarce true daca mai urmeaza o noua linie de intrare;

public String nextLine()

întoarce urmatoarea linie de la intrare;

În metodele descrise în continuare, XXX poate fi:

Boolean Byte Short Int Long Float Double BigInteger BigDecimal

Metodele hasNextXXX(), cu semnificatie evidenta, pot lansa exceptia:

IllegalStateException daca scanner-ul este închis.

Metodele nextXXX(), cu semnificatie evidenta, pot lansa exceptiile:

InputMismatchException - daca entitatea nu este cea asteptata;

NoSuchElementException - daca s-a ajuns la sfârsitul intrarii;

IllegalStateException - daca scanner-ul este închis.

Metoda:

public void close()

închide scanner-ul.










Document Info


Accesari: 3103
Apreciat:

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site

Copiaza codul
in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate




Copyright © Contact (SCRIGROUP Int. 2021 )