Eccezioni e classi di I/O
Paolo Bison
Fondamenti di Informatica 1 A.A. 2004/05
Universit`a di Padova
Errori in un programma
dati incompatibili con le istruzioni di un programma
divisione per zero
int div(int z, int y){
return z/y;
}
accesso a dati esterni
lettura da disco
int leggi(FileInputStream in){
return in.read();
}
Affrontare gli errori
tre fasi
rilevazione
segnalazione
gestione
Rilevazione dell’errore
esplicita
istruzioni che verificano la compatibilità dei dati if (y==0) <errore>;
return z/y;
implicita
il sistema run-time rileva l’errore
Segnalazione dell’errore
indicazione al chiamante di un errore
valore di ritorno
if (n<0) return -1;
variabile condivisa
if (n<0) {err=-1; return 0;}
attivazione di un segnale di errore per l’esecuzione di un “error handler”
if (n<0)
throw new IllegalArgumentException();
Gestione dell’errore
test esplicito
analisi del valore di ritorno o della variabile condivisa algoritmo + controllo errore non separati
if (fact(n)<0) <gestione errore>
fact(n); if (err<0) <gestione errore>
“error handler”
codice che viene attivato al verificarsi di un errore algoritmo + controllo errore separati
try
{ fact(n) }
catch (IllegalArgumentException ex)
{<gestione errore> }
Eccezioni in Java
oggetti che rappresentano eventi anomali
variabili d’istanza contegono valori relativi all’eccezione rappresentata
istanze di classi che estendono Throwable Throwable
..Error
..Exception
Error
condizione anormale che non dovrebbe mai accadere
Exception
condizione anormale che può essere gestita
Definizione di eccezioni
eccezioni predefinite
presenti nel sistema rappresentano errori relativi alla macchina virtuale e alle classi base
ArithmeticException
IndexOutOfBoundException
eccezioni definite dal programmatore
estensione della classe Exception o sue sottoclassi public class MyException
extends Exception{
}
Attivazione di una eccezione
esplicita
istruzione throw
throw <exception>;
public static int fact(int n){
if (n<0)
throw new UnsupportedOperationException();
if (n>10)
throw new IllegalArgumentException();
if (n==0) return 1;
else return n*fact(n-1);
}
implicita
il runtime crea un istanza di eccezione e la lancia
Gestione di una eccezione
istruzione try-catch-finally try
<block>
{ catch (<execeptId> <id>)
<block> }
almeno una clausola catch deve essere presente
Terminazione di un blocco
corretta
vengono eseguite tutte le istruzioni senza che vi sia alcun errore
anormale
se durante l’esecuzione di una istruzione del blocco vi
è un errore, il blocco termina lanciando una eccezione
Semantica del try-catch
se il blocco del try termina correttamente l’istruzione termina correttamente
se viene segnalata una eccezione, si cerca in sequenza una clausola catch che abbia come
<execeptId> la classe dell’eccezione o una sua superclasse
se questa clausola esiste, si assegna al <id> il riferimento all’eccezione e si esegue il blocco
corrispondente; la condizione di terminazione è data dalla terminazione di questo blocco
se NON esiste tale clausola, l’istruzione termina
lanciando l’eccezione
Esempio
for (i=0;i<nums.length;i++) try
{ ris[i]=fact(nums[i]);}
catch(UnsupportedOperationException e) { ris[i]=fact(-nums[i]);}
catch(IllegalArgumentException e)
{ ris[i]=0;}
Eccezioni “checked” o “unchecked”
“checked”
il compilatore verifica che i metodi lancino solamente le eccezioni che sono dichiarate nell’intestazione del metodo
clausola throws
SimpleMatrix add (SimpleMatrix x) throws InvalidMatrixException
“unchecked”
eccezioni derivate da RuntimeException e Error per le quali il compilatore non verifica la condizione
precedente
Input/Output in Java
stream
sequenza di byte o caratteri (16 bit)
flusso dal/al programma
associazione con dispositivi esterni
tastiera, video, file
Operazioni su stream
apertura
lettura
scrittura
chiusura
Package java.io
classi per la gestione dell’I/O
File
FileDescriptor InputStream
..ByteArrayInputStream ..FileInputStream
..FilterInputStream
....BufferedInputStream ....DataInputStream
....LineNumberInputStream ....PushbackInputStream ..ObjectInputStream
..PipedInputStream ..SequenceInputStream ..StringBufferInputStream
ObjectInputStream.GetField ObjectOutputStream.PutField ObjectStreamClass
ObjectStreamField OutputStream
..ByteArrayOutputStream ..FileOutputStream
..FilterOutputStream
....BufferedOutputStream ....DataOutputStream ....PrintStream
..ObjectOutputStream ..PipedOutputStream RandomAccessFile
Reader
..BufferedReader
....LineNumberReader ..CharArrayReader ..FilterReader
....PushbackReader ..InputStreamReader ....FileReader
..PipedReader ..StringReader StreamTokenizer
Writer
..BufferedWriter ..CharArrayWriter ..FilterWriter
..OutputStreamWriter ....FileWriter
..PipedWriter ..PrintWriter ..StringWriter
OutputStream
classe astratta
metodi
void write(int b) scrive un byte
void write(byte[] b)
scrive i byte contenuti in b
void write(byte[] b,int off,int len)
scrive len byte di b a partire da off
close()
chiude lo stream
IOException
InputStream
classe astratta
metodi
int read()
legge un byte e lo ritorna come int; ritorna -1 se byte non disponibile
int read(byte[] b,int off,int len)
legge al massimo len byte nell’array b a partire da off; ritorna il numero di byte letti o -1
int available()
ritorna il numero di byte che possono essere letti immediatamente
close()
chiude lo stream
Flussi standard
flussi predefiniti a run-time
associati a dispositivi esterni
individuati da variabili nella classe System
flusso disp. var. classe
std. in tastiera System.in BufferedInputStream std. out terminale System.out PrintStream
std. err terminale System.err PrintStream
PrintStream
ereditarietà
java.io.OutputStream
java.io.FilterOutputStream java.io.PrintStream
metodi
non generano IOException
void print, println (<type> arg)
stampa la rappresentazione di diversi tipi (boolean, char, char[], int, long, float, double,String, Object)
boolean checkError
ritorna true se e solo è avvenuta una IOException
BufferedInputStream
ereditarietà
java.io.InputStream
java.io.FilterInputStream
java.io.BufferedInputStream
metodi
ridefinisce i metodi dichiarati in InputStream
int read()
int read(byte[] b, int off, int len)
int available()
FileInputStream
legge bytes da un file
ereditarietà
java.io.InputStream
java.io.FileInputStream
costruttore
FileInputStream(String name)
crea un FileInputStream aprendo una connessione in lettura con il file name
metodi
ridefinisce i metodi dichiarati in InputStream
FileOutputStream
scrive bytes su un file
ereditarietà
java.io.OutputStream
java.io.FileOutputStream
costruttore
FileOutputStream(String name)
crea un FileOutputStream aprendo una connessione in scrittura con il file name
FileOutputStream(String name, boolean append)
come il precedente; se append è true le successive
operazioni di scrittura aggiungono ai dati esistenti
metodi
Lettura/scrittura file binari
classi che permettono di scrivere o leggere flussi di dati di tipo base espressi in maniera binaria
DataOutputStream
DataInputStream
la rappresentazione binaria usata è indipendente dall’architettura
file portabili
DataOutputStream
permette di scrivere elementi di tipo base in un formato binario
ereditarietà
java.io.OutputStream
java.io.FilterOutputStream java.io.DataOutputStream
i metodi possono lanciare una IOException
costruttore
DataOutputStream(OutputStream out)
crea un DataOutputStream per scrivere dati sul
stream out
DataOutputStream: metodi
oltre a ridefinire i metodi ereditati
void write(int)
void write(byte[] b, int off, int len)
definisce metodi per scrivere in forma binaria elementi di tipo base:
void writeBoolean(boolean)
void writeByte(int)
void writeBytes(String)
void writeChar(int)
void writeChars(String)
void writeDouble(double)
void writeFloat(float)
void writeInt(int)
void writeLong(long)
void writeShort(int)
void writeUTF(String)
e sapere il numero di byte scritti
int size()
DataInputStream
permette di leggere elementi di tipo base scritti in un formato binario
ereditarietà
java.io.InputStream
java.io.FilterInputStream java.io.DataInputStream
i metodi possono lanciare una IOException
costruttore
DataInputStream(InputStream in)
crea un DataInputStream per leggere dati dal
stream in
DataInputStream: metodi
oltre ad avere i soliti metodi di lettura,
definisce metodi per leggere elementi di tipo base espressi in forma binaria :
boolean readBoolean()
int readByte()
char readChar()
void readDouble(double)
float readFloat()
void readFully(byte[])
int readInt()
long readLong()
short readShort()
int readUnsignedByte()
int readUnsignedShort()
String readUTF()
e saltare un certo numero di byte
int skipBytes(int)
External Merge Sort
dati memorizzati in una struttura sequenziale
file
dimensione N dei dati deve essere potenza di 2
N = 2
kExternal Merge Sort: esempio
-7 -1 3 5 -2 6 -9 7
|
-7
|-1
|3
|5
|-2
|6
|-9
|7
||
-7
|3
|-2
|-9
||
-1
|5
|6
|7
||
-7 -1
|3 5
|-2 6
|-9 7
||
-7 -1
|-2 6
||
3 5
|-9 7
||
-7 -1 3 5
|-9 -2 6 7
||
-7 -1 3 5
||
-9 -2 6 7
||
-9 -7 -1 -2 3 6 5 7
|External Merge Sort: algoritmo
l’algoritmo si basa su due passi:
distribute
si considera il file di ingresso formato da sotto-sequenze (run) ordinate di una certa
lunghezza (all’inizio 1) e si distribuiscono queste sotto-sequenze su due file differenti
merge
si fondono le sotto-sequenze a due a due, ciascuna presa da uno dei due file generati al passo
precedente, in maniera da costruire un file
contenente sotto-sequenze ordinate di lunghezza
doppia
External Merge Sort: codice
file contiene valori interi