fluxuri in java
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