Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi...
Transcript of Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi...
Java I/O API
Java I/O
G. Grossi
10 gennaio 2007
G. Grossi Lezione 11
Java I/O API
Indice
1 Java I/O APIFlussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Il sistema I/O: questioni generali
Creare un buon sistema I/O e uno dei compiti piu difficiliper i progettisti di linguaggiQuesto fatto e evidenziato dal numero di differenti approcciLa sfida pare essere quella di volere coprire tutte leeventualita ...
riguardo ai diversi tipi di sorgenti: memoria centrale, files, laconsole, connessioni di rete, ecc.ma anche riguardo le diverse modalita di comunicazione:sequenziale, accesso casuale, bufferizzata, binaria, acaratteri, per linee, per parole (word), ecc.
Java presenta molte classi (il package java.io), la cuisomma e (solo) apparentemente confusa, in realtacontiene l’esplosione che il sistema di I/O potrebbecomportare
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di Input/Output (I/O Stream)
Per ricevere in ingresso dei dati, un programma apre unostream su una sorgente di informazioni (file, memoria,connesioni di rete) e ne legge sequenzialmente le informazioni
Applicazione
Sorgente
lettura
I N F O R M A Z I O N I
Analogamente un programma puo inviare informazioni ad undestinatario, aprendo uno stream verso di esso e scrivendosequenzialmente le informazioni in uscita
Applicazione
Destinazione
scrittura
I N F O R M A Z I O N I
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Reading e Wrinting
Il processo di lettura (Reading) di informazioni puo esseresintetizzato come segue:
open(stream)while (more information)
read(information)close(stream)
Similmente per il processo di scrittura (Wrinting):
open(stream)while (more information)
write(information)close(stream)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di byte e di caratteri
Il pacchetto java.io e composto da classi per la gestione diflussi di byte e classi per la gestione di flussi di caratteri
Flusso di byte (byte stream)I byte sono sequenze di 8-bit (come da definizione); inquesto caso si parla di I/O binario e viene usato ingenerale per i dati (es. i bit di un’immagine digitale o di unsegnale sonoro digitalizzato). I flussi di byte sono divisi influssi d’ingresso (InputStream) e flussi d’uscita(OutputStream)Flusso di caratteri (character stream)Flussi di caratteri Unicode a 16-bit; parliamo allora di I/Otestuale (es. i caratteri ascii). I flussi di caratteri sono divisiin lettori (Reader) e scrittori (Writer)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Indice
1 Java I/O APIFlussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I flussi di byte
Uno stream e un canale di comunicazione collegato ad unasorgente o destinazione attraverso il quale le unita base diinformazione (in questo caso i byte) viaggiano in sequenzaLe varie classi che realizzano gli stream di byte sidistinguono per il tipo di sorgente o destinazione con cuipossono dialogare. Sorgenti diverse, che sono legate aproblemi di implementazione o tecnologia diverserichiedono implemetazioni diverseI metodi per la lettura e scritture di byte sono comunque glistessi. In java.io sono definite due classi astratteInputStream e OutputStream che definisconol’interfaccia per gli stream di input e output rispettivamente
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di byte in input: gerarchia
<<abstract>>
InputStream
ByteArrayInputStream
PipedInputStream
FileInputStream
SequenceInputStream
<<abstract>>
FilterInputStream
StringBufferInputStream
ObjectInputStream
LineNumberInputStream
DataInputStream
BufferedInputStream
PushBackInputStream
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I canali di input
Canali tipici:Un array di byte (ByteArrayInputStream)Un oggetto String (StringBufferInputStream)Un file (FileInputStream)Una pipe che realizza lo scambio tra processi (thread)(PipedInputStream)Una sequenza da altri stream collettati insieme in unsingolo stream (SequenceInputStream)Altre sorgenti, come le connessioni ad Internet
In aggiunta la classe astratta FilterInputStream fornisceutili modalita di input per dati particolari come i tipi primitivi,meccanismi di bufferizzazione, ecc.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La classe astratta InputStream
Dichiara i metodi che permettono di leggere i byte di unasorgente specificata.
public abstract int read() throwsIOExceptionLegge un singolo byte e lo restituisce sotto forma di intero(tra 0 e 255). Se non e disponibile (fine del flusso) vienerestituito -1.public int read(byte[] buf, int offset, intcount) throws IOExceptionLegge una sequenza di byte e la memorizza in un array dibyte. Il numero massimo di byte letti e count. I bytevengono memorizzati a partire da buff[offset] sino aun massimo di buff[offset+count-1]. Restituisce -1se si e giunti alla fine del flusso e 0 se vengono letti zerobyte.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I metodi di InputStream
public long skip(long count) throwsIOExceptionAvanza lungo il flusso per un numero di byte di input pari acount. Restituisce l’effettivo numero di byte saltati *public void close() throws IOExceptionChiude il flusso di input. Andrebbe invocato per rilasciare lerisorse (es. i file) associate allo stream. Una volta invocatoquesto metodo, ulteriori operazioni sollevano eccezioni.L’implementazione fornita da InputStream non fa nulla *
* Le sottoclassi dovrebbero fornire un’implementazione piu efficiente
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di byte in output: gerarchia
<<abstract>>
OutputStream
ObjectOutputStream
PipedOutputStream
FileOutputStream
<<abstract>>
FilterOutputStream
ByteArrayOutputStream
DataOutputStream
BufferedOutputStream
PrintStream
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I canali di output
Canali tipici:ByteArrayOutputStream: crea un buffer in memoria einvia dati al bufferFileOutputStream: per inviare informazioni a un filePipedOutputStream: implementa il concetto di pipeObjectOutputStream: per inviare oggetti al destinatario
In aggiunta la classe astratta FilterOutputStream fornisceutili modalita di output per dati particolari come i tipi primitivi,meccanismi di bufferizzazione, ecc.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La classe astratta OutputStream
Fornisce un’astrazione per scrivere i byte in una certadestinazione. I metodi sono:
public abstract void write(int b) throwsIOExceptionScrive b sotto forma di byte. Il byte viene passato comeargomento di tipo int perche spesso e il risultato diun’operazione aritmetica su un byte (si evitano cosıconversioni di tipo veso il byte). Tuttavia solo gli 8 bitmeno significativi del numero intero vengono scrittipublic void write(byte[] buf, int offset,int count) throws IOExceptionScrive una parte di array di byte, a partire dabuff[offset] fino a un numero pari a count
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I metodi di OutputStream
public void flush() throws IOExceptionEffettua il flush (svuotamento) del flussopublic void close() throws IOExceptionChiude il flusso di output. Andrebbe invocato per rilasciarele risorse (es. i file) associate allo stream. Una voltainvocato questo metodo, ulteriori operazioni sollevanoeccezioni. L’implementazione di default non fa nulla *
* Le sottoclassi dovrebbero fornire un’implementazione piu efficiente
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Indice
1 Java I/O APIFlussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di byte da e verso file
Per scrivere su un file dovremo far cooperare:Un oggetto che crea fisicamente un collegamento con il file(vedi la classe File)Un oggetto che gestisce lo stream (il canale dicomunicazione verso il file) e che e in grado di inviare bytelungo lo stream (sara un’istanza di una sottoclasse diOutputStream)
In seguito vedremo anche come sia possibile “spezzare”informazioni complesse (ad esempio String, double o int)in singoli byte tali da poter essere inviati sullo stream
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Collegamento ad un file
La classe File fornisce una rappresentazione astratta edindipendente dal sistema dei pathname gerarchici (list,permessi, check esistenza, dimensioni, tipo, crea dir, rinomina,elimina)
Rappresenta solo il nome di un particolare file o il nome digruppi di file in una directoryGli oggetti di tipo File consentono di creare uncollegamento con il file fisicoSi ricordi che le interfacce utente e i sistemi operativiutilizzano pathname dipendenti dal sistema per attribuireun nome ai file e alle directory
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Pathname
Rappresentazione dei path nei sistemi Unix e Windows:Unix:/home/grossi/labprog/lez08/java/Prova.java
Windows:c:\home\grossi\labprog\lez08\java\Prova.java
La convenzione di Java e quella di rappresentare i file nelformato di Unix, ma l’interpretazione e dipendente dalsistema sottostante
Utilizzato in ambiente Windows, la barra / vieneinterpretata come \
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
File: creazione e cancellazione
public boolean createNewFile() throwsIOExceptionCrea un nuovo file vuoto con il nome specificato se e solose tale file non esistepublic boolean mkdir()Crea una directory con il nome denotato dal nome astrattopublic boolean delete()Cancella il file o la directory denotati dal nome astratto. Nelcaso di directory, allora viene cancellata solo a patto chesia vuota
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
File: metodi di test
public boolean exists()Restituisce true se e solo se il file rappresentato dalnome astratto esistepublic boolean setReadOnly()Rende il file o la directory accessibili solo in lettura.Restituisce true se e solo se l’operazione ha successopublic boolean canWrite()Restituisce true se e solo se il file denotato dal nomeastratto esiste e puo essere scrittopublic boolean canRead()Restituisce true se e solo se il file denotato dal nomeastratto esiste e puo essere letto
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
File: informazioni
public String getName()Restituisce il nome del file (o della directory) denotato dalnome astratto. E solo l’ultimo nome nella nel pathnameglobale. Se il pathname e vuoto viene restituita la stringavuotapublic String getPath()Restituisce il pathname completo del filepublic long lastModified()Restituisce un long che rappresenta la data dell’ultimamodificapublic long length()Restituisce la dimensione in bytes del file denotato dalnome astratto
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
File: esempio 1
List directoryCostruire la classe LsDir che si comporti come il comandoUnix list directory: legge il contenuto di una directoryspecificata come argomento e stampa in output l’elencoordinato dei nomi di file e dirs presenti nella dir in esame. Sequesta non viene specifcata, si considera la dir corrente (.).
(Sugg.: utilizzare il metodo list() della classe File)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
File: esempio 2
List directoryCostruire la classe MkDir che si comporti come il comandoUnix make directory: crea directory con i nomi specificati comeargomento. Inoltre se viene data l’opzione -r e due nomi(argomenti), rinomina la prima dir (se esiste) col secondonome.
Usage: MkDir path1 ... - Crea una o piu dirUsage: MkDir -r path1 path2 - Muove una dir nell’altra
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Scrivere e leggere da file
In FileInputStream tutti i metodi di InputStreamsono sovrascritti. Inoltre ha il costruttore:
public FileInputStream(File file)Crea un FileInputStream aprendo una connessione alFile specfificato
In FileOutputStream tutti i metodi di OutputStreamsono sovrascritti
public FileOutputStream(File file)Crea un FileOutputStream aprendo una connessione alFile specfificato
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Leggere e scrivere su file
Copiare fileCostruire la classe CpFile che effettui la copia di un file in unaltro gia esistente (sovrascrivendolo). Se il file destinatario nonesiste solleva l’eccezione:
FileNotFoundException("Il file: "+args[0] ...
Sugg.: Okkio alle eccezioni!!!
Uso: java CopiaFile <file_da_copiare> <file_copia>
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Scrivere dati primitivi su stream di byte
Per scrivere dati primitivi in un file di testo avremo bisogno diuna classe che consenta di convertire tali dati in sequenze dibyte. La classe PrintStream, che e un’estensioneFilterOutputStream, fornisce queste funzionalita
public PrintStream(OutputStream out)Crea un print stream verso l’output stream specificatoI metodi che mette a dispozione sono i tipici metodi discrittura:void print(boolean b), void print(char c),void print(char[] s), void print(double d),void print(float f), void print(int i), voidprint(long l), void print(Object obj), voidprint(String s)
La corrispondente versione con println
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La classe DatiPrimitivi
import java.io.*;
public class DatiPrimitivi {public static void main(String[] args) throws IOException {
File file = new File("prova.dat");FileOutputStream fos = new FileOutputStream(file);PrintStream ps = new PrintStream(fos);ps.println("Stringa");ps.println(100);ps.println(3 / 4.0);ps.println(’q’);ps.println((byte) 128);ps.println(new char[] { ’C’, ’I’, ’A’, ’O’ });ps.println(true && false);
}}
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
I flussi di I/O Standard
I concetti di standard input, standard output e standard errorsono ereditati dalle librerie C ed introdotti nell’ambiente Javacome campi statici della classe System
public static final InputStream inLo standard input System.in e usato per l’input alprogramma, tipicamente (ma non obbligatoriamente) leggel’input da tastierapublic static final PrintStream outLo standard output System.out e usato per l’output delprogramma tipicamente (ma non obbligatoriamente)mostrato a videopublic static final PrintStream errLo standard error System.err ha la funzione di mostrarea video messaggi di errore
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Indice
1 Java I/O APIFlussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di caratteri in input: gerarchia
<<abstract>>
Reader
BufferedReader
CharArrayReader
PipedReader
StringReader
FileReaderInputStreamReader
<<abstract>>
FilterReader PushbackReader
LineNumberReader
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La classe astratta Reader
Fornisce metodi analoghi a quelli della classe InputStream:public int read() throws IOExceptionLegge un singolo carattere e lo restituisce sotto forma diintero (tra 0 e 65535). Se non e disponibile (fine del flusso)viene restituito -1public abstract int read(char[] buf, intoffset, int count) throws IOExceptionLegge una sequenza di caratteri e la memorizza in unarray di char ...public int read(char[] buf) throwsIOExceptionCome public int read(buf, 0, buf.length)public boolean ready() throws IOExceptionRestituisce true se il flusso e pronto per la lettura (esistealmeno un carattere disponibile)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
InputStreamReader
Un’oggetto di questa classe costituisce un ponte fra uno streamdi byte e uno stream di caratteri. Il costruttore
InputStreamReader(InputStream in)Crea un InputStreamReader che usa la codifica deicaratteri di default del sistema
InputStreamReader e una sottoclasse di Reader quindimette a disposizione i metodi per leggere caratteri
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
FileReader
Classe di utilita per leggere file di caratteri. Il costruttoreassume che il file contenga caratteri nello schema di codificastandard. E’ un’estensione di InputStreamReaderCostruttori:
public FileReader(File file)
public FileReader(String nomefile)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Problema
Contare gli spaziDefinire una classe che conta gli spazi di un file di testospecificato come argomento o, in mancanza di argomento,dallo standard input.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Flussi di caratteri in output: gerarchia
<<abstract>>
Writer
BufferedWriter
PrintWriter
PipedWriter
StringWriter
FileWriterOutputStreamWriter
<<abstract>>
FilterWriter
CharArrayWriter
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La classe astratta Writer
Fornisce un’astrazione per scrivere i caratteri in una certadestinazione
public void write(int c) throws IOExceptionScrive c sotto forma di carattere. Il carattere viene passatocome argomento di tipo int, tuttavia solo i 16 bit menosignificativi vengono scrittipublic abstract void write(char[] buf, intoffset, int count) throws IOExceptionScrive una porzione di array di caratteri ...public void write(String s, int offset, intcount) throws IOExceptionScrive un numero di caratteri pari a count della stringa sa partire da s.charAt(offset).
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Copiare file di testo
Copiare se stessiScrivere un programma (classe Copy.java) che usaFileReader e FileWriter per copiare se stesso in un file dibackup (CopyBkup.java)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Lavorare con i Filtri
Il pacchetto java.io fornisce un insieme di classi chepermettono di concatenare dei flussi allo scopo di produrne deinuovi e maggiormente utili. I dati vengono filtrati nell’atto in cuivengono letti e scritti da uno streamEsempio:Possiamo collegare un filtro allo standard input, come segue:
BufferedReader d = new BufferedReader(new DataInputStream(System.in));
String str;while ((str = d.readLine()) != null) {
// fai qualcosa ...
}
Qui BufferedReader memorizza i dati in un buffer evitandoripetute letture allo stream
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
BufferedReader
Legge un testo da un stream di input a caratteri, bufferizza icaratteri letti in modo da fornire strumenti efficienti per leggerecaratteri, array e linee. Consente di trattare in letturadirettamente delle stringhe
public String readLine() throws IOExceptionLegge una linea di testo. Un linea e considerata conclusadai caratteri ’\n’ (line feed), a ’\r’ (carriage return), oda un carriage return seguito da un linefeed.Se non e stata raggiunta la fine dello stream restituisce lastringa contente la linea di caratteri letta ma che noninclude i caratteri di terminazione. Se e stata raggiunta lafine dello stream restituisce null
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Leggere linee da un file di testo
//collegamento al file
File file = new File(nomefile);
//stream di caratteri
FileReader fr = new FileReader(file);
//lettore bufferizzato
BufferedReader br = new BufferedReader(fr);
String riga;while ((riga = br.readLine()) != null )
System.out.println(riga);
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Leggere linee dallo standard input
Avevamo osservato che System.in e di tipo InputStream.Allora un possibile modo di leggere linee di testo dallo standardinput e il seguente
//per convertire stream di byte in strem di car.
InputStreamReader isr =new InputStreamReader(System.in);
//lettore bufferizzato
BufferedReader br = new BufferedReader(isr);
String riga;while ((riga = br.readLine()) != null )
System.out.println(riga);
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Buffering ...
Echo dell’inputScrivere la classe Echo.java che legge righe di testo da stdine, dopo aver digitato return, le ristampa su stdout.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Indice
1 Java I/O APIFlussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Scrivere e leggere oggetti ...
In molte applicazioni risulta utile scambiare oggetti informato binario, senza passare attraverso una conversionedel formato.Java fornisce a questo scopo degli strumenti per scriveresu uno stream di byte e leggere da uno stream bytedirettamente degli oggetti.Ogni classe che implementa l’interfaccia Serializablepuo essere trasformata in una sequenza di byte che puoessere successivamente ricomposta a formare l’oggettooriginale
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
... scrivere e leggere oggetti
Serializzazione: il processo che consistente nel convertirela rappresentazione di un oggetto in un flusso di byte.Deserializzazione: il processo di ricostruzione di unoggetto a partire da un flusso di byte
Questo meccanismo e applicabile anche inviando i byteattraverso la rete. Il meccanismo di serializzazione compensain modo automatico alle differenze di rappresentazione chepossono esistere fra diversi sistemi operativi.Ad esempio, e possibile creare un oggetto su una macchinaWindows, serializzarlo, inviarlo attraverso la rete a unamacchina Unix dove sara correttamente ricostruito.
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Le classi
ObjectOutputStreamfornisce metodi per convertire un oggetto o un datoprimitivo in una sequenza di byte per poi inviarlo lungo unOutputStream
ObjectInputStreamfornisce metodi per convertire una sequenza di byteproveniente da un InputStream in un oggetto o in datoprimitivo
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
ObjectOutputStream
Costruttore:public ObjectOutputStream(OutputStream out)throws IOExceptionCrea un ObjectOutputStream che scrivesull’OutputStream specificato
Metodi:public final void writeObject(Object obj)throws IOExceptionScrive uno specifico oggetto sull’ObjectOutputStreamMetodi per scrivere dati primitivi:writeDouble(double data), writeFloat(floatdata), writeInt(int data), writeLong(longdata), ...
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
ObjectInputStream
Costruttore:public ObjectInputStream(InputStream in)throws IOExceptionCrea un ObjectInputStream che leggedall’InputStream specificato
Metodi:public final Object readObject() throwsOptionalDataException,ClassNotFoundException, IOExceptionLegge un oggetto dall’ObjectInputStreamMetodi per leggere dati primitivi:double readDouble(), float readFloat(), intreadInt(), long readLong() ...
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Scrivere oggetti
FileOutputStream out =new FileOutputStream("dataOdierna");
ObjectOutputStream s = new ObjectOutputStream(out);s.writeObject("Data di oggi: ");s.writeObject(new Data());s.flush();
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
La serializzazione va richiesta
Attenzione: gli oggetti non sono automaticamente serializzabiliUn oggetto puo contenere dati che non si vuole sianoaccessibli dall’esterno (come una password).Una volta serializzata e, ad esempio memorizzata su file,tale informazione puo essere recuperata anche se nellaclasse originale era dichiarata privataPer poter scrivere (o leggere) gli oggetti di una classequesta deve dichiarare esplicitamente di ammettere laserializzazione implementando l’interfaccia markerSerializable
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Serializable
Si tratta di un’interfaccia vuota!Non contiene nessun metodo, per questo motivo vieneanche detta classe marcatrice (marker)Per rendere una classe serializzabile e sufficientedichiarare che implementa l’interfaccia Serializable;non occorre implementare alcun metodoimport java.io.Serializable;
public class MiaClasse implements Serializable {...
}
Esempio:public final class String implements Serializable
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Leggere oggetti
Il seguente codice legge gli oggetti scritti nello stream objectdell’esempio precedente (deve essere collegato a unInputStream)
FileInputStream in =new FileInputStream("dataOdierna");
ObjectInputStream s = new ObjectInputStream(in);String oggi = (String)s.readObject();Date date = (Date)s.readObject();
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Deserializzazione: esperimento
File: Alieno.java
import java.io.Serializable;public class Alieno implements Serializable {}
File: ScriviAlieno.java
import java.io.FileOutputStream;import java.io.ObjectOutputStream;import java.io.IOException;
public class ScriviAlieno {public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("fileAlieno.bin");ObjectOutputStream oos = new ObjectOutputStream(fos);Alieno et = new Alieno();oos.writeObject(et);
}}
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Leggiamolo...
Compiliamo ed eseguiamo: viene generato il file binariofileAlieno.binFile: LeggiAlieno.java
import java.io.FileInputStream;import java.io.ObjectInputStream;import java.io.IOException;
public class LeggiAlieno {public static void main(String[] args) throws Exception {FileInputStream fis=new FileInputStream("fileAlieno.bin");ObjectInputStream ois = new ObjectInputStream(fis);Object alieno = ois.readObject();System.out.println(alieno.getClass());
}}
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Esecuzione
Leggiamolo ora in una directory che non contiene la classeAlieno
> java LeggiAlienoException in thread "main" java.lang.ClassNotFoundException: Alienoat java.net.URLClassLoader$1.run(URLClassLoader.java:200)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:188)at java.lang.ClassLoader.loadClass(ClassLoader.java:297)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)at java.lang.ClassLoader.loadClass(ClassLoader.java:253)at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)at java.lang.Class.forName0(Native Method)at java.lang.Class.forName(Class.java:195)at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:654)at java.io.ObjectInputStream.inputClassDescriptor(ObjectInputStream.java:918)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:366)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1186)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:386)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)at LeggiAlieno.main(LeggiAlieno.java:11)
G. Grossi Lezione 11
Java I/O API
Flussi di byte in input/outputLeggere e scrivere su fileFlussi di caratteri in input/outputSerializzazione/Deserializzazione
Quindi ...
Per poter recuperare la struttura dell’oggetto una volta lettonecessario che la JVM possa accedere a tutte le classiche sono state coinvolte nel processo di serializzazione.Nel caso precedente ponendo la classe compilataAlieno.class nella directory in cui e eseguitaLeggiAlieno si ottiene:> java LeggiAlienoclass Alieno
G. Grossi Lezione 11