La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

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.

Presentazioni simili


Presentazione sul tema: "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."— Transcript della presentazione:

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 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)

2 IL PACKAGE java.io Le quattro classi base astratte di java.io Object InputStream Reader OutputStream Writer

3 IL PACKAGE java.io Tratteremo separatamente prima gli stream di byte –InputStream e OutputStream poi gli stream di caratteri –Reader e Writer

4 STREAM DI BYTE La classe base InputStream definisce metodi 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.

5 STREAM DI BYTE La classe base OutputStream definisce metodi per: scrivere uno o più byte ( write() ) svuotare il buffer di uscita ( flush() ) chiudere lo stream ( close() )

6 STREAM DI BYTE Dalle classi base astratte si derivano molte classi concrete che specializzano lI/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

7 STREAM DI BYTE

8 STREAM DI BYTE - INPUT Da InputStream derivano in primis: ByteArrayInputStream –linput è un array di byte, passato al costruttore di ByteArrayInputStream FileInputStream –linput è 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

9 STREAM DI BYTE - INPUT Le altre classi derivate da InputStream hanno come scopo avvolgere un altro InputStream per creare unentità con funzionalità più evolute. Il loro costruttore ha quindi come parametro un InputStream

10 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

11 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(),..)

12 IL CASO DI System.in Loggetto 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);

13 STREAM DI BYTE - OUTPUT Da OutputStream derivano in primis: ByteArrayOutputStream –loutput è un array di byte interno, dinami- camente espandibile, recuperabile con i metodi toByteArray() o toString(), secondo i casi FileOutputStream –loutput è 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

14 STREAM DI BYTE - OUTPUT Le altre classi derivate da OutputStream hanno come scopo avvolgere un altro OutputStream per creare unentità con funzionalità più evolute. Il loro costruttore ha quindi come parametro un OutputStream

15 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

16 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() )

17 IL CASO DI System.out Loggetto 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);

18 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 cerano

19 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

20 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

21 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...

22 ESEMPIO 1 (segue) DataOutputStream os = new DataOutputStream(fs); float f1 = F; char c1 = 'X'; boolean b1 = true; double d1 = ; 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); }

23 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

24 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...

25 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); }

26 IL PACKAGE java.io Stream di caratteri ( Reader e Writer ) Le classi per lI/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 linternazionalizzazione).

27 STREAM DI CARATTERI La classe base Reader definisce metodi per: leggere uno o più caratteri ( read() ) sapere se lo stream è pronto per linput ( ready() ) saltare N byte in input ( skip() ) ricavare la posizione corrente sullo stream ( mark() ) e tornarci ( reset() ), sempreché markSupported() sia vero.

28 STREAM DI CARATTERI La classe base Writer definisce metodi per: scrivere uno o più caratteri ( write() ) svuotare il buffer di uscita ( flush() ) chiudere lo stream ( close() )

29 STREAM DI CARATTERI Dalle classi base astratte si derivano molte classi concrete che specializzano lI/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.

30 STREAM DI CARATTERI

31 STREAM DI CARATTERI - INPUT Da Reader derivano in primis: CharArrayReader –linput è un array di caratteri, passato al costruttore di CharArrayReader StringReader –linput è una stringa di caratteri, passata al costruttore di StringReader BufferedReader –linput è un altro Reader (wrapping) –aggiunge la capacità di lettura bufferizzata (in particolare, un metodo readLine() )

32 STREAM DI CARATTERI - INPUT Un caso particolarissimo di Reader è l InputStreamReader, che reinterpreta un 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 !

33 IL CASO DI System.in Loggetto 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);

34 STREAM DI CARATTERI - INPUT Da InputStreamReader deriva poi FileReader –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

35 STREAM DI CARATTERI - OUTPUT Da Writer derivano in primis: CharArrayWriter –loutput è un array di caratteri StringWriter –linput è una stringa di caratteri BufferedWriter –linput è un altro Writer (wrapping) –aggiunge la capacità di scrittura bufferizzata

36 STREAM DI CARATTERI - OUTPUT Un caso particolarissimo di Writer è l OutputStreamWriter, che reinterpreta un 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 !

37 IL CASO DI System.out Loggetto 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);

38 STREAM DI CARATTERI - OUTPUT Da OutputStreamWriter deriva poi FileWriter –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

39 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

40 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 = F; char c1 = 'X'; boolean b1 = true; double d1 = ;

41 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){...} }

42 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: true1.4142X12

43 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 lEOF

44 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...

45 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); }

46 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ù true1.4142X12 ma true X 12

47 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(); }...

48 ESEMPIO 4 - UNA VARIANTE La versione precedente ha letto dal file ununica 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

49 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(); }

50 LESEMPIO 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); }

51 LESEMPIO 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 –...

52 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

53 ESEMPIO 5 Leggere da input una serie di token Avvolgiamo il reader che fornisce linput 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', ' ');

54 ESEMPIO 5 Poi: Predisponiamo un ciclo che ripeta res = t.nextToken(); e guardiamo cosa abbiamo letto:

55 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...

56 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); }

58 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

59 SERIALIZZAZIONE DI OGGETTI Una classe che voglia essere serializ- zabile deve implementare linterfaccia 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 dellog- getto, inclusi quelli ereditati (anche se privati o protetti)

60 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.

61 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;} }

62 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...

63 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); }

64 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...

65 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


Scaricare ppt "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."

Presentazioni simili


Annunci Google