65
IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file binari del C) Reader e Writer per leggere/scrivere stream di caratteri (da Java 1.1 in poi) (come i file di testo del C)

IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

Embed Size (px)

Citation preview

Page 1: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL PACKAGE java.io

Il package java.io definisce quattro classi base astratte:

InputStream e OutputStream per leggere/scrivere stream di byte (come i file binari del C)

Reader e Writer per leggere/scrivere stream di caratteri (da Java 1.1 in poi)(come i file di testo del C)

Page 2: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL PACKAGE java.io

Le quattro classi base astratte di java.io

Object

InputStreamReader OutputStream Writer

Page 3: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL PACKAGE java.io

Tratteremo separatamente

• prima gli stream di byte

– InputStream e OutputStream

• poi gli stream di caratteri

– Reader e Writer

Page 4: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE

La classe base InputStream definiscemetodi per:

leggere uno o più byte (read())

sapere quanti byte sono disponibili in input (available())

saltare N byte in input (skip())

ricavare la posizione corrente sullo stream (mark()) e tornarci (reset()) , sempreché markSupported() sia vero.

Page 5: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE

La classe base OutputStream definiscemetodi per:

scrivere uno o più byte (write())

svuotare il buffer di uscita (flush())

chiudere lo stream (close())

Page 6: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE

Dalle classi base astratte si derivano molteclassi concrete che specializzano l’I/O per:

I/O da array di byte

I/O da file

I/O filtrato caso particolare: I/O di tipi primitivi

Java (int, float, ...) caso particolare: I/O bufferizzato

I/O di oggetti

Page 7: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTEObject

InputStream

SequenceInputStream

OutputStream

ByteArrayInputStream

FileInputStream

ObjectInputStream

PipedInputStream

FilterInputStream

ByteArrayOutputStream

FileOutputStream

ObjectOutputStream

PipedOutputStream

FilterOutputStream

BufferedInputStream

DataInputStream

BufferedOutputStream

DataOutputStream

PrintStream

FileFileDescriptor

Page 8: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - INPUT

Da InputStream derivano in primis:• ByteArrayInputStream

– l’input è un array di byte, passato al costruttore di ByteArrayInputStream

• FileInputStream– l’input è un file, il cui nome è passato al

costruttore di FileInputStream– in alternativa si può passare al costruttore

un oggetto File costruito a parte, o anche un FileDescriptor

Page 9: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - INPUT

Le altre classi derivate da InputStreamhanno come scopo avvolgere un altroInputStream per creare un’entità confunzionalità più evolute.

Il loro costruttore ha quindi come parametroun InputStream

InputStream

BufferedInputStream

Page 10: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - INPUT

Le due classi principali sono:• ObjectInputStream

– legge oggetti serializzati salvati su stream– offre metodi per leggere i tipi primitivi e le

classi standard (Integer, etc.) di Java

• FilterInputStream– definisce il concetto di “filtro”– modifica il metodo read(), e se occorre

anche altri, in modo da effettuare le letture in accordo al criterio di filtraggio richiesto

– in pratica si usano le sue sottoclassi

Page 11: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - INPUT

Le sottoclassi di FilterInputStream:• BufferedInputStream

– modifica il metodo read() in modo da leggere tramite un buffer (che aggiunge)

– definisce il nuovo metodo readLine(), che però è deprecato in Java 1.1 perché sostituito dalle classi Reader

• DataInputStream– definisce metodi per leggere tipi di dati

standard in forma binaria (readInteger(), readFloat(),..)

Page 12: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL CASO DI System.in

• L’oggetto statico System.in , lo standard input, è appunto un InputStream

• viene praticamente sempre “avvolto” (wrapped) in un tipo di InputStream più evoluto per comodità

• Ad esempio:

BufferedInputStream input = new BufferedInputStream(System.in);

System.in

BufferedInputStream

Page 13: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - OUTPUT

Da OutputStream derivano in primis:• ByteArrayOutputStream

– l’output è un array di byte interno, dinami-camente espandibile, recuperabile con i metodi toByteArray() o toString(), secondo i casi

• FileOutputStream– l’output è un file, il cui nome è passato al

costruttore di FileOutputStream– in alternativa si può passare al costruttore un

oggetto File costruito a parte, o anche un FileDescriptor

Page 14: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - OUTPUT

Le altre classi derivate da OutputStreamhanno come scopo avvolgere un altroOutputStream per creare un’entità confunzionalità più evolute.

Il loro costruttore ha quindi come parametroun OutputStream

OutputStream

BufferedOutputStream

Page 15: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - OUTPUT

Le due classi principali sono:• ObjectOutputStream

– scrive oggetti serializzati salvati su stream– offre metodi per scrivere i tipi primitivi e le

classi standard (Integer, etc.) di Java

• FilterOutputStream– definisce il concetto di “filtro”– modifica il metodo write(), e se occorre

anche altri, in modo da svolgere le scritture in accordo al criterio di filtraggio richiesto

– in pratica si usano le sue sottoclassi

Page 16: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI BYTE - OUTPUT

Le sottoclassi di FilterOutputStream:• BufferedOutputStream

– modifica il metodo write() in modo da scrivere tramite un buffer (che aggiunge)

• DataOutputStream– fornisce metodi per scrivere in forma bina-ria

tipi di dati standard (writeInteger(),..)

• PrintStream– definisce metodi per stampare sotto forma di

stringa i tipi primitivi (print()) e le classi standard (mediante toString())

Page 17: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL CASO DI System.out

• L’oggetto statico System.out, lo standard output, è appunto un OutputStream

• viene praticamente sempre “avvolto” (wrapped) in un tipo di OutputStream più evoluto per comodità

• Ad esempio:BufferedOutputStream output = new BufferedOutputStream(System.out);

System.out

BufferedOutputStream

Page 18: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

System.in e System.out

Attenzione:

• Lo standard input (System.in) e lo standard output (System.out) sono in effetti stream di caratteri

• Dovrebbero essere definiti come Reader e Writer, rispettivamente

• Invece, sono definiti come InputStream e OutputStream per motivi di compatibilità

– in Java 1.0 Reader e Writer non c’erano

Page 19: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

System.in e System.out

Quindi, bisogna fare attenzione:

• anche se definiti come InputStream e OutputStream per motivi di compatibilità, rimangono stream di caratteri

• Non ha senso scrivere su essi dati in forma binaria

– in output, si vedrebbero quadratini e faccine

– in input, si leggerebbero valori casuali

• Si possono “trasformare” in Reader e Writer con alcune classe apposite

Page 20: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 1

Scrittura di dati su file binario

• Per scrivere su un file binario occorre un FileOutputStream, che però consente solo di scrivere un byte o un array di byte

• Volendo scrivere dei float, int, double, boolean, … è molto più pratico un DataOutputStream, che ha metodi idonei

• Quindi, si incapsula il FileOutputStream in un DataOutputStream

Page 21: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 1

import java.io.*;

public class Esempio1 {

public static void main(String args[]){FileOutputStream fs = null;try { fs = new FileOutputStream("Prova.dat");}

catch(IOException e){ System.out.println("Apertura fallita"); System.exit(1);}// continua...

Page 22: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 1 (segue)

DataOutputStream os = new DataOutputStream(fs);

float f1 = 3.1415F; char c1 = 'X';boolean b1 = true; double d1 = 1.4142;

try { os.writeFloat(f1); os.writeBoolean(b1); os.writeDouble(d1); os.writeChar(c1); os.writeInt(12); os.close();} catch (IOException e){ System.out.println("Scrittura fallita"); System.exit(2);}

}}

Page 23: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 2

Rilettura di dati da file binario

• Per leggere da un file binario occorre un FileInputStream, che però consente solo di leggere un byte o un array di byte

• Volendo leggere dei float, int, double, boolean, … è molto più pratico un DataInputStream, che ha metodi idonei

• Quindi, si incapsula il FileInputStream in un DataInputStream

Page 24: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 2

import java.io.*;

public class Esempio2 {

public static void main(String args[]){

FileInputStream fin = null;

try { fin = new FileInputStream("Prova.dat");}catch(FileNotFoundException e){ System.out.println("File non trovato"); System.exit(3);}

// continua...

Page 25: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 2 (segue)

DataInputStream is = new DataInputStream(fin);

float f2; char c2; boolean b2; double d2; int i2;

try { f2 = is.readFloat(); b2 = is.readBoolean(); d2 = is.readDouble(); c2 = is.readChar(); i2 = is.readInt(); is.close(); System.out.println(f2 + ", " + b2 + ", " + d2 + ", " + c2 + ", " + i2);} catch (IOException e){ System.out.println("Errore di input"); System.exit(4);}

}

Page 26: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL PACKAGE java.io

Stream di caratteri (Reader e Writer)

• Le classi per l’I/O da stream di caratteri sono più efficienti di quelle a byte

• convertono correttamente la codifica UNICODE di Java in quella locale

– specifica della piattaforma in uso (tipicamente ASCII)

– e della lingua in uso (essenziale per l’internazionalizzazione).

Page 27: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI

La classe base Reader definisce metodiper:

leggere uno o più caratteri (read())

sapere se lo stream è pronto per l’input (ready())

saltare N byte in input (skip())

ricavare la posizione corrente sullo stream (mark()) e tornarci (reset()) , sempreché markSupported() sia vero.

Page 28: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI

La classe base Writer definisce metodiper:

scrivere uno o più caratteri (write())

svuotare il buffer di uscita (flush())

chiudere lo stream (close())

Page 29: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI

Dalle classi base astratte si derivano molteclassi concrete che specializzano l’I/O per:

I/O da array di caratteri e da stringhe I/O bufferizzato

I/O da stream di byte

caso particolare: I/O da file

I/O filtrato

I/O da pipe

Il metodo read() restituisce caratteri UNICODE.

Page 30: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI

Object

Reader

BufferedReader

File

Writer

CharArrayReader

InputStreamReader

StringReader

PipedReader

FilterReader

BufferedWriter

CharArrayWriter

OutputStreamWriter

StringWriter

PipedWriter

FilterWriter

PrintWriter

FileReader

FileWriter

FileDescriptor

Page 31: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - INPUT

Da Reader derivano in primis:• CharArrayReader

– l’input è un array di caratteri, passato al costruttore di CharArrayReader

• StringReader– l’input è una stringa di caratteri, passata al

costruttore di StringReader

• BufferedReader– l’input è un altro Reader (“wrapping”)– aggiunge la capacità di lettura bufferizzata (in

particolare, un metodo readLine())

Page 32: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - INPUT

Un caso particolarissimo di Reader èl’InputStreamReader, che reinterpretaun InputStream come un Reader

• È il ponte fra il mondo dei generici stream di byte (Java 1.0) e il mondo degli stream di caratteri (Java 1.1)

• Consente di “vedere” qualunque stream di byte come uno stream di caratteri

– ovviamente, ha senso solo se da quello stream provengono realmente caratteri !

Page 33: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL CASO DI System.in

• L’oggetto statico System.in, lo standard input, è formalmente un InputStream...

• ... ma in realtà è uno stream di caratteri!• Può essere “trasformato virtualmente” in

un Reader incapsulandolo con un InputStreamReader

• Tipicamente:

InputStreamReader kbd = new InputStreamReader(System.in);

System.in

InputStreamReader

Page 34: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - INPUT

Da InputStreamReader deriva poiFileReader

– in pratica, costruisce un FileInputStream e lo incapsula in un InputStreamReader

– velocizza questa operazione, consentendo di costruire direttamente un FileReader a partire dal nome del file (una stringa)

– in alternativa si può passare al costruttore un oggetto File costruito a parte, o anche un FileDescriptor

Page 35: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - OUTPUT

Da Writer derivano in primis:• CharArrayWriter

– l’output è un array di caratteri

• StringWriter– l’input è una stringa di caratteri

• BufferedWriter– l’input è un altro Writer (“wrapping”)– aggiunge la capacità di scrittura

bufferizzata

Page 36: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - OUTPUT

Un caso particolarissimo di Writer èl’OutputStreamWriter, che reinterpretaun OutputStream come un Writer

• È il ponte fra il mondo dei generici stream di byte (Java 1.0) e il mondo degli stream di caratteri (Java 1.1)

• Consente di “vedere” qualunque stream di byte come uno stream di caratteri

– ovviamente, ha senso solo se quello stream accetta realmente caratteri !

Page 37: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

IL CASO DI System.out

• L’oggetto statico System.out, lo standard output, è formalmente un OutputStream...

• ... ma in realtà è uno stream di caratteri!• Può essere “trasformato virtualmente” in

un Writer incapsulandolo con un OutputStreamWriter

• Tipicamente:

OutputStreamWriter video = new OutputStreamWriter(System.out);

System.out

OutputStreamWriter

Page 38: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

STREAM DI CARATTERI - OUTPUT

Da OutputStreamWriter deriva poiFileWriter

– costruisce un FileOutputStream e lo incapsula in un OutputStreamWriter

– velocizza questa operazione, consentendo di costruire direttamente un FileWriter a partire dal nome del file (una stringa)

– in alternativa si può passare al costruttore un oggetto File costruito a parte, o anche un FileDescriptor

Page 39: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3

Scrittura di dati su file di testo

• Per scrivere su un file di testo occorre un FileWriter, che però consente solo di scrivere un carattere o una stringa

• Volendo scrivere dei float, int, double, boolean, … occorre convertirli in stringhe a priori con il metodo toString() della classe corrispondente, e poi stamparli

– Non esiste qualcosa di simile allo stream DataOutputStream

Page 40: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3

import java.io.*;

public class Esempio3 {

public static void main(String args[]){FileWriter fout = null;try { fout = new FileWriter("Prova.txt");}

catch(IOException e){ System.out.println("Apertura fallita"); System.exit(1);}float f1 = 3.1415F; char c1 = 'X';boolean b1 = true; double d1 = 1.4142;

Page 41: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3 (segue)

try { String buffer = null; buffer = Float.toString(f1); fout.write(buffer,0,buffer.length()); buffer = new Boolean(b1).toString(); fout.write(buffer,0,buffer.length()); buffer = Double.toString(d1); fout.write(buffer,0,buffer.length()); fout.write(c1); // singolo carattere buffer = Integer.toString(12); fout.write(buffer,0,buffer.length()); fout.close();} catch (IOException e){...}

}}

Page 42: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3 - note

• Il nostro esempio ha stampato sul file le rappresentazioni sotto forma di stringa di svariati valori...

• ... ma non ha inserito spazi intermedi !

• Ha perciò scritto:

3.1415true1.4142X12

Page 43: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 4

Rilettura di dati da file di testo

• Per leggere da un file di testo occorre un FileReader, che però consente solo di leggere un carattere o una stringa

• Occorre quindi un ciclo che legga carat-tere per carattere fino alla fine del file

– il metodo ready() restituisce true finché ci sono altri caratteri da leggere

– il metodo read() restituisce il carattere letto sotto forma di int, perché -1 indica l’EOF

Page 44: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 4

import java.io.*;

public class Esempio4 {

public static void main(String args[]){

FileReader fin = null;

try { fin = new FileReader("Prova.txt");}catch(FileNotFoundException e){ System.out.println("File non trovato"); System.exit(3);}

// continua...

Page 45: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 4 (segue)

try {

while(fin.ready()){ char ch = (char) fin.read(); System.out.print(ch); // echo }

System.out.println("");

}

catch (IOException e){ System.out.println("Errore di input"); System.exit(4);}

}

Page 46: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3 - UNA VARIANTE

• La versione precedente ha stampato sul file le rappresentazioni sotto forma di stringa di svariati valori, ma non ha inserito spazi intermedi

• Aggiungiamo uno spazio fra i valori, in modo da stampare

• non più 3.1415true1.4142X12• ma 3.1415 true 1.4142 X 12

Page 47: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 3 - VARIANTE

try { String buffer = null; buffer = Float.toString(f1) + " "; fout.write(buffer,0,buffer.length()); buffer = new Boolean(b1).toString() + " "; fout.write(buffer,0,buffer.length()); buffer = Double.toString(d1) + " "; fout.write(buffer,0,buffer.length()); fout.write(c1); // singolo carattere fout.write(' '); buffer = Integer.toString(12) + " "; fout.write(buffer,0,buffer.length()); fout.close();}

...

Page 48: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 4 - UNA VARIANTE

• La versione precedente ha letto dal file un’unica stringa ininterrotta

– non poteva far altro, mancando gli spazi

• Ora però gli spazi fra i valori ci sono:ergo, possiamo definire una funzione statica readField() che legga un campo fino al successivo spazio

– non può essere un metodo, perché esso dovrebbe far parte della classe FileReader, che non possiamo modificare

Page 49: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 4 - readField()

static public String readField(Reader in){

StringBuffer buf = new StringBuffer();boolean nospace = true;try { while(in.ready() && nospace){

char ch = (char)in.read(); nospace = (ch!=' '); if (nospace) buf.append(ch);

}} catch (IOException e){ System.out.println("Errore di input"); System.exit(4);}return buf.toString();

}

Page 50: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

L’ESEMPIO 4 RIFORMULATO

// continua... try {

while(fin.ready()){ String s = readField(fin); System.out.println(s); // echo }

}

catch (IOException e){ System.out.println("Errore di input"); System.exit(4);}

}

Page 51: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

L’ESEMPIO 4 RIFORMULATO

• In questo modo, siamo in grado di leggere una stringa alla volta

• Ogni stringa può quindi essere interpre-tata nel modo che le è proprio...

• ...applicando, se occorre, la conversione opportuna

– nessuna conversione per le stringhe– conversione stringa / int per gli interi– conversione stringa / float per i reali– ...

Page 52: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

StreamTokenizer

• La classe StreamTokenizer consente di leggere da input una serie di “token”

• Può estrarre da uno stream (reader) sia numeri sia stringhe, in modo configurabile– whitespaceChars(int lo, int hi)

registra come separatori i caratteri da lo a hi– nextToken() estrae il token successivo, che

viene posto nel campo pubblico sval (se è una stringa) o nval (se è un numero)

– il valore restituito nextToken() da indica se si tratta di un numero o di una stringa

Page 53: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 5

Leggere da input una serie di token

• Avvolgiamo il reader che fornisce l’input con uno StreamTokenizer

t = new StreamTokenizer(reader);

• Configuriamo lo StreamTokenizer per assumere come separatori (“spazi”) tutti i caratteri fra lo '\0' e lo spazio ' '

t.whitespaceChars('\0' , ' ');

Page 54: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 5

Poi:

• Predisponiamo un ciclo che ripeta

res = t.nextToken();

• e guardiamo cosa abbiamo letto:

Se nextToken() ha letto res vale la costanteuna stringa StreamTokenizer.TT_WORD

un numero StreamTokenizer.TT_NUMBER

un fine linea (“End of Line”) StreamTokenizer.TT_EOL

il fine file (“End of File”) StreamTokenizer.TT_EOF

Page 55: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 5

import java.io.*;

public class Esempio5 {

public static void main(String args[]){

FileReader f = null;// ... apertura del file...

StreamTokenizer t = new StreamTokenizer(f);t.whitespaceChars(0, (int)' ');

int res = -1;

do { try { res = t.nextToken(); } catch (IOException e) { ... } // ... continua ...

Page 56: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 5

// ... continua ...

if (res == StreamTokenizer.TT_WORD) { String s = new String(t.sval);

System.out.println("stringa: " + s); } else

if (res == StreamTokenizer.TT_NUMBER) {double d = t.nval;System.out.println("double: " + d);

}

} while( res != StreamTokenizer.TT_EOL &&res != StreamTokenizer.TT_EOF);

}}

Page 57: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

SERIALIZZAZIONE DI OGGETTI

• Serializzare un oggetto significa salvare un oggetto scrivendo una sua rappresen-tazione binaria su uno stream di byte

• Analogamente, deserializzare un oggetto significa ricostruire un oggetto a partire dalla sua rappresentazione binaria letta da uno stream di byte

• Le classi ObjectOutputStream e Object-InputStream offrono questa funzionalità per qualunque tipo di oggetto.

Page 58: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

SERIALIZZAZIONE DI OGGETTI

Le due classi principali sono:• ObjectInputStream

– legge oggetti serializzati salvati su stream, tramite il metodo readObject()

– offre anche metodi per leggere i tipi primitivi di Java

• ObjectOutputStream– scrive un oggetto serializzato su stream,

tramite il metodo writeObject()– offre anche metodi per scrivere i tipi primitivi

di Java

Page 59: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

SERIALIZZAZIONE DI OGGETTI

• Una classe che voglia essere “serializ-zabile” deve implementare l’interfaccia Serializable

• È una interfaccia vuota, che serve come marcatore (il compilatore rifiuta di compi-lare una classe che usi la serializzazione senza implementare tale interfaccia)

• Vengono scritti / letti tutti i dati dell’og-getto, inclusi quelli ereditati (anche se privati o protetti)

Page 60: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

SERIALIZZAZIONE DI OGGETTI

• Se un oggetto contiene riferimenti ad altri oggetti, si invoca ricorsivamente writeObject() su ognuno di essi

– si serializza quindi, in generale, un intero grafo di oggetti

– l'opposto accade quando si deserializza

• Se uno stesso oggetto è referenziato più volte nel grafo, viene serializzato una sola volta, affinché writeObject() non cada in una ricorsione infinita.

Page 61: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 6

Una piccola classe serializzabile...

public class Punto2D implements java.io.Serializable {

float x, y;public Punto2D(float x, float y) {

this.x = x; this.y = y; }public Punto2D() { x = y = 0; }public float ascissa(){ return x; }public float ordinata(){ return y;}}

Page 62: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 6

...e un main che ne fa uso

public class Esempio6 {public static void main(String[] args) {

FileOutputStream f = null;

try { f = new FileOutputStream("xy.bin");

} catch(IOException e){System.exit(1);

}

// ... continua...

Page 63: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 6

// ... continua ...

ObjectOutputStream os = null;

Punto2D p = new Punto2D(3.2F, 1.5F);

try {

os = new ObjectOutputStream(f);os.writeObject(p); os.flush(); os.close();

} catch (IOException e){System.exit(2);

} }}

Page 64: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 7

Rilettura da stream di oggetti serializzati

public class Esempio7 {public static void main(String[] args) {

FileInputStream f = null; ObjectInputStream is = null;

try { f = new FileInputStream("xy.bin");is = new ObjectInputStream(f);

} catch(IOException e){System.exit(1);

}

// ... continua...

Page 65: IL PACKAGE java.io Il package java.io definisce quattro classi base astratte: InputStream e OutputStream per leggere/scrivere stream di byte (come i file

ESEMPIO 7

// ... continua ...

Punto2D p = null;

try { p = (Punto2D) is.readObject(); is.close();

} catch (IOException e1){System.exit(2); }

catch (ClassNotFoundException e2){System.exit(3); }

System.out.println("x,y = " + p.ascissa() + ", " + p.ordinata());

}}

Il cast è necessario, perché readObject() restituisce un Object