Input / Output
Spesso un programma deve acquisire dati da una sorgente
esterna o inviare informazioni a una destinazione esterna.
L’informazione puo’ essere di ogni tipo: caratteri, immagini, suoni,
oggetti.
1
Input / Output
Stream di Input / Output
Per acquisire dati, un programma apre uno stream associato alla sorgente di
informazione (file, socket, memoria, ecc.) e legge l’informazione
sequenzialmente da esso.
In modo analogo, un programma puo’ inviare verso una destinazione esterna
dei dati aprendo uno stream associato alla destinazione e scrivendovi in modo
sequenziale i dati.
Indipendentemente dall’origine e dalla destinazione dei dati e dal loro tipo, gli
algoritmi per leggere e scrivere sequenzialmente dei dati sono gli stessi.
2
Stream di Input / Output
3
Input / Output
Lettura
Scrittura
Apertura dello stream
Finché e’ presente informazione
leggi l’informazione
Chiudi lo stream
Apertura dello stream
Finché e’ presente informazione
scrivi l’informazione
Chiudi lo stream
4
Tipi di Stream
Le classi di gestione degli stream si dividono sono di due tipi in base al tipo di
dato su cui operano.
Stream di Caratteri: classi Reader e Writer
Stream di Byte: classi InputStream e OutputStream (di solito usati per
leggere file di immagini e suoni).
Le classi InputStreamReader e OutputStreamWriter consentono
di trasformare stream di byte in stream di caratteri. Un
InputStreamReader legge byte e li converte in caratteri.
Le classi BufferedReader e BufferedWriter vengono utilizzate per
leggere/scrivere blocchi di dati (caratteri a 16 bit) riducendo cosi’ il numero di
accessi alla sorgente/destinazione.
BufferedReader(Reader in)
BufferedWriter(Writer out)
5
Gestione di Stream di caratteri
6
Gestione di Stream di byte
7
La classe System
Talvolta un programma richiede l’accesso alle risorse del sistema, allo standard output,
allo standard input, ecc. La piattaforma Java consente di effettuare l’accesso alle
risorse del sistema attraverso l’uso della classe System.
La classe System fornisce lo stream in (di tipo InputStream) associato allo
standard input, lo stream out associato allo output e lo stream err associato allo
standard error.
Inoltre contiene alcuni metodi che svolgono diversi compiti. Ad esempio il metodo
currentTimeMillis() fornisce il tempo in millisecondi (a partire dal 1/1/1970), il
metodo exit(int status) interrompe l’interpretazione del programma, ecc.
8
FileReader
Normalmente un flusso viene creato a partire da un file su disco.
Per interagire con un file di caratteri occorre quindi creare un oggetto di tipo FileReader
FileReader(String fileName)
esistono anche altri costruttori
Esempio:
FileReader in = new FileReader(“nome-file”);
9
java.lang.Object
|
+--java.io.Reader
|
+--java.io.InputStreamReader
|
+--java.io.FileReader
FileReader
public FileReader(String fileName)
throws FileNotFoundException
Crea un nuovo FileReader, per leggere dal file il cui nome viene passato come parametro.
Parametri:
FileName – nome del file da leggere
Throws:
FileNotFoundException – se il file specificato non esiste
10
BufferedReader
Un BufferedReader permette di gestire un flusso tramite un buffer:
I dati vengono letti a blocchi dal flusso e memorizzati in un buffer
Quando viene richiesto un nuovo dato prima si verifica la sua disponibilità nel
buffer, se non disponibile si legge un nuovo blocco
Costruttori disponibili
BufferedReader(Reader in)
Crea un oggetto BufferedReader a partire da un oggetto Reader
Metodi disponibili in aggiunta a quelli di Reader
String readLine()
Legge una riga e la restituisce sotto forma di stringa
11
Copia di un file
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
// dal java-tutorial
import java.io.*;
public class Copy {
public static void main(String[] args) {
FileReader in = new FileReader(args[0]);
FileWriter out = new FileWriter(args[1]);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
}
12
Copia di un file
Copy.java:7: Exception java.io.FileNotFoundException must be
caught, or it must be declared in the throws clause of this
method.
FileReader in = new FileReader(args[0]);
^
Copy.java:8: Exception java.io.IOException must be caught, or it
must be declared in the throws clause of this method.
FileWriter out = new FileWriter(args[1]);
^
2 errors
13
Copia di un file
1. import java.io.*;
2.
3. public class Copy {
4.
public static void main(String[] args) {
5.
try {
6.
FileReader in = new FileReader(args[0]);
7.
FileWriter out = new FileWriter(args[1]);
8.
9.
int c;
10.
while ((c = in.read()) != -1)
11.
out.write(c);
12.
}
13.
catch(FileNotFoundException e) {
14.
System.err.println(e);
15.
System.exit(1);
16.
}
17.
catch(IOException e) {
18.
System.err.println(e);
19.
System.exit(1);
20.
}
21. …
14
Copia di un file
Copy.java:19: : Exception java.io.IOException must be caught, or
it must be declared in the throws clause of this method.
while ((c = in.read()) != -1)
^
1 error
15
Copia di un file
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
// dal java-tutorial
import java.io.*;
public class Copy {
public static void main(String[] args)
throws IOException {
FileReader in = new FileReader(args[0]);
FileWriter out = new FileWriter(args[1]);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
}
16
Copia di un file
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
// dal java-tutorial
import java.io.*;
public class CopyBytes {
public static void main(String[] args)
throws IOException {
FileInputStream in = new FileInputStream(args[0]);
FileOutputStream out = new FileOutputStream(args[1]);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
}
17
PrintStream
La classe PrintStream mette a disposizione i metodi print e println
utilizzabili con qualunque tipo di parametro.
Si può creare un nuovo oggetto PrintStream a partire da un OutputStream, in
particolare da un FileOutputStream.
PrintStream f = new PrintStream(
new FileOutputStream(“nome-file”) );
Gli oggetti System.out e System.err sono di tipo PrintStream
18
Classe File
Serve per ottenere informazioni riguardo un file, non tratta file aperti
Nota bene:
Creare un oggetto ti tipo File non significa creare un file fisico
Costruttori disponibili
File(String pathname)
Crea un oggetto di tipo File a partire da una stringa (il pathname)
File(File parent, String child)
Crea un oggetto di tipo File avente come nome child a partire
dalla directory parent (descritta tramite un oggetto di tipo File)
File(String parent, String child)
Crea un oggetto di tipo File avente come nome child a partire
dalla directory parent
19
Proprietà di un file
1. import java.io.File;
2.
3. public class FileInfo {
4.
5.
public static void main(String[] args)
6.
throws java.io.IOException {
7.
File f = new File("FileInfo.class");
8.
System.out.println(f.exists());
9.
System.out.println(f.isFile());
10.
System.out.println(f.isDirectory());
11.
System.out.println(f.canRead());
12.
System.out.println(f.canWrite());
13.
System.out.println(f.length());
14.
System.out.println(f.getAbsolutePath());
15.
System.out.println(f.getName());
16.
System.out.println(f.getParent());
17.
File p = new File(f.getAbsolutePath());
18.
System.out.println(p.getParent());
19.
}
20. }
true
true
false
true
True
919
E:\Prove\FileInfo.class
FileInfo.class
null
E:\Prove
20
File
Metodi disponibili
boolean delete()
Cancella il file o la directory specificata
boolean mkdir()
Crea la directory
boolean renameTo(File dest)
Cambia nome al file
String[] list()
Restituisce un vettore con i nomi dei file della directory riferita
dall’oggetto File
File[] listFiles()
Restituisce un vettore con gli oggetti File che fanno riferimento ai
file della directory riferita dall’oggetto File
…
21
Listato di una directory
1. import java.io.File;
2.
3. public class Lista {
4.
5.
public static void main(String[] args) {
6.
File workingDir = new File(".");
7.
String[] lista = workingDir.list();
8.
for(int i=0; i<lista.length; i++) {
9.
System.out.println(lista[i]);
10.
}
11.
}
12.
13. }
Lista.java
Lista.class
Copy.java
Provare a creare un equivalente del comando ls -l
Copy.class
FileInfo.java
FileInfo.class
22
Eccezioni
Un’eccezione è un oggetto che descrive una situazione inusuale o erronea.
Le eccezioni vengono lanciate da un programma o dalla macchina virtuale, e possono,
se lo si desidera essere intercettate e gestite.
Si puo’ gestire un’eccezione nei seguenti tre modi:

Non gestire l’eccezione;

Gestire l’eccezione non appena si verifica;

Gestire l’eccezione in un altro punto del programma.
23
Gestione delleEccezioni
Se un’eccezione viene ignorata dal programma, allora il programma stesso verra’
interrotto producendo un messaggio di errore opportuno.
Il messaggio include il tipo di eccezione lanciata e la pila delle chiamate che
consentono di individuare il punto del programma in cui l’eccezione si e’ verificata.
24
Il blocco try
Per gestire un’eccezione occorre inserire l’istruzione che puo’ lanciare l’eccezione all’interno di un
blocco try.
Un blocco try e’ seguito da una o piu’ clausole catch che contengono le istruzioni che servono
a gestire la/e eccezione/i.
Ogni clausola catch e’ associata ad un tipo di eccezione.
Ogni blocco try puo’ avere piu’ clausole catch associate.
Ogni clausola catch viene detta gestore di eccezioni.
Quando viene eseguito un blocco try, vengono eseguite tutte le istruzioni contenute nel blocco.
Se non si verificano eccezioni, l’esecuzione continua poi con le istruzioni che seguono il blocco
try (dopo la clausola catch).
Se si verifica un’eccezione all’interno di un blocco try, il controllo passa al gestore di eccezioni
appropriato. Dopo l’esecuzione delle istruzioni della clausola catch, il controllo passa alle
istruzioni che seguono l’intero blocco try - catch.
25
Gestione delle eccezioni
Se un’eccezione non viene intercettata e gestita quando si verifica, il controllo viene
immediatamente restituito al metodo che ha invocato il metodo che l’ha prodotta.
Le eccezioni si propagano finchè si incontra un metodo che intercetta e gestisce
l’eccezione, oppure finchè non termina anche il metodo main.
Per intercettare un’eccezione ad un livello piu’ esterno, il metodo che produce
l’eccezione deve essere invocato all’interno di un blocco try che possieda la
clausola catch appropriata per gestirla.
Le eccezioni possono essere lanciate da un metodo al chiamante con la clausola
throws che segue l’intestazione della definizione del metodo. La clausola
throws serve per indicare che quel metodo puo’ lanciare o propagare una
particolare eccezione, se si verifica.
public static void main(String[] args)
throws IOException {
26
Eccezioni controllate
Le eccezioni controllate richiedono che il metodo in cui si possono verificare le
intercetti e le gestisca direttamente o le elenchi nella clausola throws.
27
1. import java.io.*;
2.
3. public class ProvaEccezione {
4.
5.
private String d;
6.
7.
public ProvaEccezione(String dati) {
8.
d = dati;
9.
}
10.
11.
public static ProvaEccezione[] leggiFile(String fileName)
12.
throws IOException {
13.
ProvaEccezione[] dati = new ProvaEccezione[50];
14.
15.
File f = new File(fileName);
16.
if(!f.canRead()) {
17.
throw new IOException("Il file "+fileName+" non e' leggibile");
18.
}
19.
BufferedReader in = new BufferedReader(new FileReader(f));
20.
for(int i=0; i<dati.length; i++) {
21.
String line = in.readLine();
22.
if(line == null) throw new EOFException(
23.
"Incontrato EOF durante la lettura di "+fileName);
24.
dati[i] = new ProvaEccezione(line);
25.
}
26.
in.close();
27.
return dati;
28.
}
29. }
Esempio di eccezioni
28
Esempio di eccezioni
1. import java.io.*;
2.
3. public class ProvaEccezione {
4.
5.
public static final String
6.
msg = "Durante la lettura si e' incontrato il seguente errore:\n“,
7.
prompt = "vuoi leggere un altro file? ";
8.
9.
public static void main(String[] args) {
10.
String fileName = args.length>0 ? args[0] : "ProvaEccezione.java";
11.
while(fileName != null && fileName.length()>0) {
12.
try {
13.
leggiFile(fileName);
14.
break;
15.
}
16.
catch(IOException e) {
17.
System.out.println(msg+e.getMessage());
18.
fileName = MyUtility.readLine(prompt).trim();
19.
}
20.
}
21.
}
22.
23. }
29
Clausola finally
Al blocco try si puo’ associare la clausola opzionale finally che definisce una
sezione di codice che viene eseguita indipendentemente da come si sia usciti dal
blocco try.
Spesso si utilizza per gestire risorse o per garantire che alcune parti dell’algoritmo
vengano eseguite comunque.
30
Classe StringTokenizer
La classe StringTokenizer class e’ definita nel package java.util.
Un oggetto StringTokenizer separa una stringa in sottostringhe dette token.
Per default, il tokenizer separa la stringa ad ogni spazio.
Il costruttore StringTokenizer richiede come parametro la stringa da separare.
Ciascuna chiamata al metodo nextToken restituisce il token successivo.
31
public void write ()
{
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < n; i++)
out.println("Value at: " + i + " = " + v[i]);
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("ArrayIndexOutOfBoundsException: "
+ e.getMessage());
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
32
// MyUtility
import java.io.*;
public class MyUtility {
private static BufferedReader console=new BufferedReader(new
InputStreamReader(System.in));
public static String readLine(String prompt)
{
try {
System.out.println(prompt);
return console.readLine();
} catch(IOException e) {
System.err.println(e);
System.exit(1);
}
return null;
}
}
33