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.
Appunti di Informatica Prof. Accarino
2
Lettura da e scrittura su file
Tastiera
File
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.
Memoria
Rete
Monitor
File
Memoria
Rete
Appunti di Informatica Prof. Accarino
3
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)


In modalità binaria i dati manipolati sono byte.


Le classi coinvolte terminano in -Reader, -Writer
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
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);
}
Appunti di Informatica Prof. Accarino
14
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
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);
}
Appunti di Informatica Prof. Accarino
16
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 len
byte 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 binario
public 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 binario
public 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 binario
public 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.
impiegato
Mansione
imp
DataAssu
Data
Se si esegue out.writeObject(imp) vengono scritti in out
sia l'oggetto Impiegato che l'oggetto Data.
Appunti di Informatica Prof. Accarino
30