Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi...

58
Java I/O API Java I/O G. Grossi 10 gennaio 2007 G. Grossi Lezione 11

Transcript of Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi...

Page 1: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

Java I/O API

Java I/O

G. Grossi

10 gennaio 2007

G. Grossi Lezione 11

Page 2: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 3: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 4: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 5: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 6: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 7: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 8: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 9: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 10: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 11: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 12: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 13: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 14: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 15: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 16: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 17: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 18: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 19: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 20: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 21: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 22: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 23: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 24: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 25: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 26: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 27: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 28: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 29: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 30: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 31: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 32: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 33: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 34: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 35: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 36: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 37: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 38: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 39: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 40: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 41: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 42: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 43: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 44: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 45: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 46: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 47: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 48: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 49: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 50: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 51: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 52: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 53: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 54: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 55: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 56: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 57: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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

Page 58: Java I/Oprog.di.unimi.it/laboratorio/lezioni/lez11.pdf · Java I/O API Indice 1 Java I/O API Flussi di byte in input/output Leggere e scrivere su file Flussi di caratteri in input/output

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