File e Stream In Java - prof.accarino.altervista.org File.pdf · Lettura da e scrittura su file...
Transcript of File e Stream In Java - prof.accarino.altervista.org File.pdf · Lettura da e scrittura su file...
File e Stream In Java
Prof. Francesco Accarino
IIS Sesto San Giovanni
Via Leopardi 132
Lettura da e scrittura su file
Java fornisce operazioni di input/output tramite le classi del package java.io.
La struttura è indipendente dalla piattaforma.
Le operazioni si basano sul concetto di flusso.
Un flusso (stream) è una sequenza ordinata di
dati che ha una sorgente e una destinazione.
L’ordine della sequenza è importante: possiamo
pensare a un nastro che viene inciso o riprodotto in un
ordine prefissato, un dato dopo l’altro.
2Appunti di Informatica Prof. Accarino
Lettura da e scrittura su fileTastiera
File
Memoria
Rete
Monitor
File
Memoria
Rete
Gli Stream sono un’astrazione messa a disposizione dai
moderni Sistemi Operativi che permettono alle applicazioni di
prelevare informazioni da varie sorgenti o inviare informazioni
a varie destinazioni.
3Appunti di Informatica Prof. Accarino
Lettura da e scrittura su file
L’uso degli stream maschera la specifica natura
fisica di una sorgente o una destinazione.
Si possono trattare oggetti differenti allo stesso modo,
ma anche oggetti simili in modi differenti.
In particolare, esistono due modi principali:
modalità testo(per esempio, per file di testo o per
l’output a console video): immediato per l’utente
modalità binaria(per dati elaborati): si leggono e
scrivono byte, risultati non immediati per l’utente
Appunti di Informatica Prof. Accarino 4
Lettura da e scrittura su file
In modalità testo i dati manipolati sono in forme simili al tipo char di Java. (Caratteri ASCII) Le classi coinvolte terminano in -Reader, -Writer
In modalità binaria i dati manipolati sono byte. Le tipiche classi coinvolte si chiamano gestori di flussi e hanno
il prefisso–(Input/Output)Stream
Per entrambi i casi abbiamo già visto le
applicazioni riguardanti lettura da tastiera e
scrittura a video (con conversioni da byte a
stringhe)
Appunti di Informatica Prof. Accarino 5
Il file system
Il tipo File può contenere un riferimento a un
file fisico del sistema. Il riferimento è creato da
un costruttore con un parametro di tipo stringa
che rappresenta il path-name del file.
File x = new File(“temp.tmp”); associa il file
temp.tmp all’oggetto File di nome x.
La classe dispone di utili metodi boolean: exists(), canRead(), canWrite(), isFile(),
isDirectory()
Appunti di Informatica Prof. Accarino 6
Il file system
La classe File ha poi altri metodi utili, come:
length(): ritorna il valore in byte
list(): se invocato su una cartella, ritorna i
nomi dei file in un array di stringhe
setReadable(),setWritable(), setReadOnly():
imposta diritti di lettura/scrittura
createNewFile(),mkdir(): crea file/cartella
delete(): cancella file/cartella
getParent(): ritorna la cartella madre (./..)
Appunti di Informatica Prof. Accarino 7
Lettura/Scrittura verso file di testo
Per gestire testi, Java fornisce due gerarchie, in
lettura (Reader) e in scrittura (Writer).
Reader e Writer sono due classi astratte che
servono a definire i metodi di base per lettura e
scrittura da file. Sono compresi:
flush()/close(): scarica/scarica+chiude flusso
read()/write(): leggi/scrivi pacchetti di char
L’implementazione specifica di questi metodi
dipende dall’estensione che si usa.
Appunti di Informatica Prof. Accarino 8
Gerarchia di Reader
Appunti di Informatica Prof. Accarino 9
Gerarchia di Writer
Appunti di Informatica Prof. Accarino 10
Scrittura su file di testo Per aprire un file di testo, tipicamente si crea un oggetto
di tipo FileWriter. (Stream Di Scrittura)
La classe FileWriter ha due costruttori che come
parametro hanno il riferimento al file espresso o come un
oggetto di tipo File o direttamente dalla stringa che
contiene il path-name completo del file su cui scrivere). File f= new File(“Prova.txt”); FileWriter fw= new FileWriter(f);
FileWriter fw= new FileWriter((“Prova.txt”);
A sua volta, FileWriter è incapsulato in un oggetto di tipo
PrintWriter. Per utilizzare metodi più performanti come
println() con i quale scriviamo sul file una intera linea
PrintWriter pw = new PrintWriter(fw); pw.println(“riga di testo”);
Appunti di Informatica Prof. Accarino 11
Scrittura su file di testo
La classe PrintWriter è contenuta nel
package java.io e serve a fornire gli stessi
metodi della classe PrintStream(visti ad
esempio per la sua istanza System.out).
Solo, invece di stampare testo a video, lo scrivono
sul file associato.
Quindi si possono utilizzare i metodi print() e
println() di PrintWriter per scrivere caratteri in
un file aperto con successo.
Appunti di Informatica Prof. Accarino 12
Il metodo printf
Print e println sono metodi versatili: sono in
grado di stampare tipi diversi di dato.
PrintWriter (e PrintStream) hanno anche un
metodo di stampa formattata: printf.
N
Notare che i metodi di PrintWriter non
sollevano eccezioni
Appunti di Informatica Prof. Accarino 13
Esempio di scrittura file di testo
Appunti di Informatica Prof. Accarino 14
publicstatic voidstampaCostanti()
{ f = new File(“costanti.txt”);
if ( f.exists() )
{ System.out.println(“costanti.txt esiste!”);
return;
}
String[] nomi = { “Pi greco”, “Nepero” };
double[] valori = { Math.PI, Math.E };
FileWriter fw = new FileWriter(f);
PrintWriter pw = new PrintWriter(fw);
for ( int i = 0; i<nomi.length; i++)
{
pw.printf(“%s è:%10.6f”,nomi[i],valori[i]);
}
close(f);
}
Lettura da file di testo
Analogamente alla scrittura, per leggere da
file si creerà invece un oggetto FileReader.
Anche in questo caso il costruttore può
ricevere un parametro File o stringa.
Tuttavia, un FileReader dovrebbe leggere un
carattere alla volta, quindi di solito viene
incapsulato in un oggetto BufferedReader:
BufferedReader r = new BufferedReader(new FileReader(“a.dat”));
Appunti di Informatica Prof. Accarino 15
Esempio di lettura file di testo
Appunti di Informatica Prof. Accarino 16
publicstatic voidstampaIlFile()
{
f = new File(“a.txt”);
if ( !f.exists() )
{ System.out.println(“a.txt non esiste!”);
return;
}
FileReader fr = new FileReader(f);
BufferedReader re = new BufferedReader(fr);
String linea = re.readLine();
while (linea != null){
System.out.println(linea);
linea = re.readLine();
}
close(f);
}
Scrittura file in modalità append
Di default il contenuto di un file viene
sovrascritto. Se invece volessimo inserire
nuovi caratteri in fondo a un file preesistente
esistono ulteriori costruttori:
FileWriter(File, boolean)
FileWriter(String, boolean)
che chiedono se vogliamo fare un append (in
tal caso la variabile boolean = true).
Appunti di Informatica Prof. Accarino 17
File Binari
Le classi che Java mette a disposizione per leggere e scrivere file binari, sono rispettivamente :
java.io.FileInputStream
java.io.FileOutputStream.
La classe FileInputStream è l’analogo della classe FileReader che viene utilizzata per leggere i dati da un file di testo.
La classe FileOutputStream è l’analogo della classe FileWriter che viene utilizzata per scrivere i dati in un file di testo.
Creazione dell’istanza
Per ottenere un’istanza della classe FileInputStream, che ci permette di aprire un file binario in modalità lettura, possiamo utilizzare uno dei seguenti costruttori della classe:
FileInputStream(File file) che riceve in ingresso un’istanza della classe File.
FileInputStream(FileDescriptor fdObj) che riceve in ingresso un’istanza della classe FileDescriptor.
che riceve in ingresso una stringa cheFileInputStream(String name) rappresenta il path del file.
Tutti e tre i costruttori possono sollevare un’eccezione FileNotFoundException qualora il file non viene trovato oppure non può essere aperto.
Gerarchia delle classi
Appunti di Informatica Prof. Accarino 20
Metodi di letura Per leggere un byte si utilizza il metodo read(), che restituisce il
byte sottoforma di numero intero compreso tra 0 e 255.
Il metodo read può sollevare un’eccezione, IOException, se per qualche motivo il byte corrente non può essere letto.
Esistono 3 versioni differenti del metodo read:
int read() che permette di leggere un byte a partire dalla posizione corrente.
int read(byte[ ] b) che permette di leggere b.length byte dal file. I byte letti vengono memorizzati nel byte array b.
int read(byte[] b, int off, int len) che permette di leggere lenbyte dal file a partire dalla posizione off. I byte letti vengono memorizzati nel byte array b.
Quando la fine del file viene raggiunta (EOF End of file), il metodo read restituisce -1.
Al termine della lettura il file può essere chiuso invocando il metodo close().
Lettura di un file binariopublic static void read(){int c;
try{FileInputStream fis = new FileInputStream(new File("prova.bin"));c = fis.read();while (c != -1){
c = fis.read();}fis.close();}catch (FileNotFoundException e) {
e.printStackTrace();}catch (IOException e) {
e.printStackTrace(); }
}
FileOutputStream
Per creare un’istanza della classe FileOutputStream, che ci permette di aprire un file binario in modalità scrittura, possiamo utilizzare uno dei seguenti costruttori della classe:
FileOutputStream(File file) che riceve in ingresso un’istanza della classe File.
FileOutputStream(File file, boolean append) che riceve in ingresso un’istanza della classe File ed apre il file in modalità append.
FileOutputStream(FileDescriptor fdObj) che riceve in ingresso un’istanza della classe FileDescriptor.
FileOutputStream(String name) che riceve in ingresso una stringa che rappresenta il path del file.
FileOutputStream(String name, boolean append) che riceve in ingresso una stringa che rappresenta il path del file ed apre il file in modalità append.
Anche in questo caso può essere sollevata un’eccezione FileNotFoundException qualora il file non viene trovato oppure non può essere aperto in modalità scrittura.
Scrittura di un file binario Per scrivere un byte all’interno del file occorre invocare il
metodo write(int c) che riceve in ingresso un valore intero rappresentante il gruppo degli 8 bit meno significativi del byte.
Esistono 3 versioni differenti del metodo write:
void write(int b) che permette di scrivere il byte b nel file.
void write(byte[] b) che permette di scrivere b.length byte nel file.
void write(byte[] b, int off, int len) che permette di scrivere nel file len byte prelevati dal byte array b a partire dalla posizione off.
Al termine delle operazioni di scrittura, il file deve essere chiuso invocando il metodo close(), per assicurarsi che il contenuto dei buffer di sistema sia effettivamente trasferito sul file.
Scrittura di un file binariopublic static void write(){int i = 1;try{
FileOutputStream fos = new FileOutputStream(new File("test.bin"));while (i<10){fos.write(i);i++;}
fos.close();}catch (FileNotFoundException e){e.printStackTrace();
}catch (IOException e){e.printStackTrace();
}}
Copia di un file binariopublic static void copia(){int c;try{
FileOutputStream fos = new FileOutputStream(new File("out.jpg"));FileInputStream fis = new FileInputStream(new File("in.jpg"));c = fis.read();while (c != -1){c = fis.read();fos.write(c);
}fis.close();fos.close();
}catch (FileNotFoundException e){e.printStackTrace();
}catch (IOException e){e.printStackTrace();
}}
Lettura e scrittura di tipi primitivi
Le classi DataInputStream e DataOutputStream
Forniscono metodi per leggere e scrivere dati primitivi
I dati vengono codificati in formato binario e non sono leggibili come
testi.
DataOutputStream dout = new DataOutputStream(
new FileOutputStream("prova.dat"));
dout.writeInt(250);
dout.writeDouble(3.14);
dout.writeChar('a');
dout.close();
DataInputStream din = new DataInputStream(
new FileInputStream("prova.dat"));
System.out.println(din.readInt());
System.out.println(din.readDouble());
System.out.println(din.readChar());
Appunti di Informatica Prof. Accarino 27
I/O di oggetti
In Java è possibile leggere o scrivere qualunque oggetto
con ObjectInputStream e ObjectOutputStream.
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("impiegati.dat"));
Impiegato rossi = new Impiegato(......);
out.writeObject(rossi);
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("impiegati.dat"));
Impiegato imp = (Impiegato)in.readObject();
Appunti di Informatica Prof. Accarino 28
I/O di oggetti
E' possibile leggere o scrivere un oggetto solo se questo
appartiene ad una classe che implementa l'interfaccia
Serializable.
class Impiegato implements Serializable(...)
L'interfaccia Serializable non contiene nessun metodo.
Deve essere specificata solo per motivi di sicurezza.
Quando si legge un oggetto, Java controlla che la
definizione della classe non sia cambiata da quando
l'oggetto era stato scritto.
Appunti di Informatica Prof. Accarino 29
I/O di oggetti
Cosa succede se si scrive un oggetto che contiene
riferimenti ad altri oggetti?
Vengono scritti anche tutti gli altri oggetti raggiungibili.
Appunti di Informatica Prof. Accarino 30
impDataAssu
Mansione
Data
Se si esegue out.writeObject(imp) vengono scritti in out
sia l'oggetto Impiegato che l'oggetto Data.
impiegato