Lavorare con i File e gestire
le Eccezioni
Anno Accademico 2003/04
Docente modulo 2: Barbara Masucci
Due modi per memorizzare i dati
„
Formato testo
Dati rappresentati come sequenze di
caratteri
‰ 12345 memorizzato come ‘1’ ‘2’ ‘3’ ‘4’ ‘5’
‰
„
Formato binario
Dati rappresentati come sequenze di
byte
‰ 12345 memorizzato come 00 00 48 57
‰
Linguaggi di Programmazione II
2003-04
2
1
Elaborare dati in ingresso e in
uscita
„
Formato testo
‰
„
Usare le classi Reader e Writer e le
loro sottoclassi
Formato binario
‰
Usare le classi InputStream e
OutputStream e le loro sottoclassi
Linguaggi di Programmazione II
2003-04
3
Leggere dati da un file
ƒ Per dati di testo, creare un oggetto di
tipo FileReader
ƒ FileReader reader = new
FileReader("in.txt");
ƒ Per dati binari, creare un oggetto di
tipo FileInputStream
ƒ FileInputStream inputStream = new
FileInputStream("in.dat");
Linguaggi di Programmazione II
2003-04
4
2
Scrivere dati in un file
ƒ Per dati di testo, creare un oggetto di
tipo FileWriter
ƒ FileWriter writer = new
FileWriter(“out.txt");
ƒ Per dati binari, creare un oggetto di
tipo FileOutputStream
ƒ FileOutputStream outputStream = new
FileOutputStream(“out.dat");
Linguaggi di Programmazione II
2003-04
5
Dove sono tutte queste classi?
ƒ Le classi
ƒ FileReader, FileWriter,
FileInputStream, FileOutputStream
sono nel package java.io
Linguaggi di Programmazione II
2003-04
6
3
Leggere dati di testo da un file
ƒ Il metodo read della classe Reader
legge un carattere alla volta
ƒ restituisce un int che rappresenta il
carattere letto (va convertito in un
char)
ƒ restituisce -1 se il file è terminato
ƒ Alla fine bisogna chiudere il file
Linguaggi di Programmazione II
2003-04
7
Leggere dati di testo da un file
FileReader reader = new FileReader("in.txt");
//legge il prossimo carattere
int next = reader.read();
char c;
//se il file non è terminato fai il cast a char
if (next != -1)
c = (char)next;
//chiudi il file
reader.close()
Linguaggi di Programmazione II
2003-04
8
4
Leggere dati binari da un file
ƒ Il metodo read della classe InputStream
legge un byte alla volta
ƒ restituisce un int che rappresenta il byte
letto (va convertito in un byte)
ƒ restituisce -1 se il file è terminato
ƒ Alla fine bisogna chiudere il file
Linguaggi di Programmazione II
2003-04
9
Leggere dati binari da un file
FileInputStream inputStream = new
FileInputStream("in.dat");
//legge il prossimo byte
int next = inputStream.read();
byte b;
//se il file non è terminato, fai il cast a byte
if (next != -1)
b = (byte)next;
//chiudi il file
inputStream.close();
Linguaggi di Programmazione II
2003-04
10
5
Scrivere dati di testo in un file
ƒIl metodo write della classe Writer scrive
un carattere alla volta
FileWriter writer = new
FileWriter("out.txt");
...
char c='';
...
writer.write(c); ...
write.close();
Linguaggi di Programmazione II
2003-04
11
Scrivere dati binari in un file
ƒIl metodo write della classe
FileOutputStream scrive un byte alla volta
FileOutputStream output = new
FileOutputStream("out.dat");
...
byte b = 0;
...
output.write(b);
...
write.close();
Linguaggi di Programmazione II
2003-04
12
6
Errori comuni
ƒ Quando si digita il path di un file ogni
barra rovesciata va inserita due volte
ƒ Una singola barra rovesciata è un carattere
speciale!
FileReader reader = new
FileReader(“C:\\nomedir\\nomefile.txt");
Linguaggi di Programmazione II
2003-04
13
Scrivere file di testo
ƒ Usiamo un oggetto di tipo PrintWriter
per
ƒ Spezzare numeri e stringhe in singoli
caratteri
ƒ Inviarli uno alla volta a un oggetto di tipo
FileWriter
FileWriter writer = new FileWriter(“out.txt”);
PrintWriter out = new PrintWriter(writer);
Linguaggi di Programmazione II
2003-04
14
7
Scrivere file di testo
Possiamo usare i metodi print e println
della classe PrintWriter per stampare
numeri, oggetti e stringhe
out.println(29.95);
out.println(new Rectangle(5,10,15,25));
out.println("Hello, World!");
Linguaggi di Programmazione II
2003-04
15
Scrivere file di testo
I metodi print e println
ƒ
ƒ
ƒ
usano toString per ottenere una
rappresentazione degli oggetti sotto forma di
stringa
scompongono le stringhe in singoli caratteri
inviano i singoli caratteri all’oggetto di tipo
FileWriter
Linguaggi di Programmazione II
2003-04
16
8
Leggere file di testo
ƒ Usiamo un oggetto di tipo BufferedReader
ƒ Il metodo readLine della classe
BufferedReader legge una linea alla volta
ƒ Chiama il metodo read dell’oggetto di tipo
Reader per leggere un carattere alla volta
fino ad ottenere una linea
ƒ Quando i dati sono terminati restituisce null
Linguaggi di Programmazione II
2003-04
17
Leggere file di testo
FileReader reader = new FileReader ("input.txt");
BufferedReader in = new BufferedReader(reader);
//leggi i dati
String inputLine = in.ReadLine();
//converti i dati letti (stringhe) in numeri
double x = Double.parseDouble(inputLine);
Linguaggi di Programmazione II
2003-04
18
9
La classe File
ƒ
Descrive i file e le cartelle su disco
ƒ
Creiamo un oggetto di tipo
File
File inputFile = new File("input.txt");
ƒ
ƒ
Non possiamo leggere direttamente dati
da un oggetto di tipo File
Dobbiamo costruire un oggetto di tipo
FileReader o FileWriter
FileReader reader = new FileReader(inputFile);
Linguaggi di Programmazione II
2003-04
19
La classe File: alcuni metodi
„ delete
-Cancella il file
„ renameTo
-Rinomina il file
„ exists
-Restituisce true se il file esiste già
Linguaggi di Programmazione II
2003-04
20
10
Finestre per la selezione di file
ƒ
ƒ
Per consentire all’utente la selezione di un
file da una finestra, creiamo un oggetto di
tipo JFileChooser
Invochiamo il metodo showOpenDialog o
showSaveDialog
ƒ
ƒ
Diverse etichette del pulsante (Open o Save)
Specifichiamo il componente sul quale la
finestra deve apparire
ƒ
null se non ci interessa quale sia
Linguaggi di Programmazione II
2003-04
21
Finestre per la selezione di file
Linguaggi di Programmazione II
2003-04
22
11
Finestre per la selezione di file
ƒ
I metodi invocati restituiscono
ƒ
JFileChooser.APPROVE_OPTION
se l’utente sceglie
un file
ƒ
JFileChooser.CANCEL_OPTION
se l’utente preme
Cancel
ƒ
Se viene scelto un file, il metodo
GetSelectedFile restituisce l’oggetto di
tipo File che descrive il file
Linguaggi di Programmazione II
2003-04
23
Finestre per la selezione di file
//crea la finestra di dialogo
JFileChooser chooser new JFileChooser();
FileReader in = null;
//se l’utente ha scelto un file
//indica qual’è e crea un oggetto FileReader
if (chooser.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION)
{
File selectedFile =
chooser.getSelectedFile();
in = new FileReader(selectedFile);
}
Linguaggi di Programmazione II
2003-04
24
12
Eccezioni
ƒ Una eccezione è una condizione di errore
ƒ In presenza di una eccezione un metodo
potrebbe
ƒ restituire un valore che indica il fallimento
ƒ trasferire il controllo a un gestore delle
eccezioni, al fine di ripristinare una situazione
corretta
Linguaggi di Programmazione II
2003-04
25
Eccezioni
ƒ
Se individuiamo una condizione di
errore, lanciamo (throw) una eccezione
ƒ
Il metodo termina immediatamente e
passa il controllo al gestore delle
eccezioni
Linguaggi di Programmazione II
2003-04
26
13
Sintassi: lanciare un’eccezione
throw exceptionObject;
Esempio:
throw new IllegalArgumentException();
Scopo:
Lanciare un’eccezione e trasferire il controllo a un
gestore di eccezioni di quel tipo
Linguaggi di Programmazione II
2003-04
27
Esempio
public class BankAccount
{
public void withdraw(double amount)
{
if (amount > balance)
throw new IllegalArgumentException(
"Amount exceeds balance");
balance = balance - amount;
}
...
}
Linguaggi di Programmazione II
2003-04
28
14
Gerarchia delle
classi di eccezioni
Linguaggi di Programmazione II
2003-04
29
Tipi di Eccezioni
ƒ Due categorie:
ƒ eccezioni controllate
ƒ dovute a circostanze esterne che il
programmatore non può evitare
ƒ il compilatore vuole sapere cosa fare nel
caso l’eccezione venga lanciata
ƒ eccezioni non controllate
ƒ dovute a circostanze che il programmatore
può evitare
Linguaggi di Programmazione II
2003-04
30
15
Tipi di eccezioni
ƒ Esempio di eccezione controllata
ƒ EOFException: terminazione inaspettata del
flusso di dati in ingresso
ƒ Può essere provocata da eventi esterni
ƒ errore del disco
ƒ interruzione del collegamento di rete
ƒ Il gestore dell’eccezione si occupa del
problema
Linguaggi di Programmazione II
2003-04
31
Tipi di eccezioni
ƒ Esempio di eccezione non controllata
ƒ NullPointerException: uso di un
riferimento null
ƒ Errore che il programmatore può prevenire,
controllando che il riferimento non sia null
prima di usarlo!
ƒ Non bisogna installare un gestore per questo
tipo di eccezione
Linguaggi di Programmazione II
2003-04
32
16
Eccezioni controllate
ƒ Tutte le sottoclassi di IOException
ƒ
ƒ
ƒ
ƒ
EOFException
FileNotFoundException
MalformedURLException
UnknownHostException
ƒ ClassNotFoundException
ƒ CloneNotSupportedException
Linguaggi di Programmazione II
2003-04
33
Eccezioni non controllate
ƒ Tutte le sottoclassi di RunTimeException
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ArithmeticException
ClassCastException
IllegalArgumentException
IllegalStateException
IndexOutOfBoundsException
NoSuchElementException
NullPointerException
Linguaggi di Programmazione II
2003-04
34
17
Eccezioni controllate e non controllate
Linguaggi di Programmazione II
2003-04
35
Segnalare eccezioni
„
BufferedReader.readLine può lanciare una
IOException
„
Un metodo che chiama readLine può
‰
‰
gestire l’eccezione, cioè dire al compilatore cosa
fare
non gestire l’eccezione, ma dichiarare di poterla
lanciare
„
In tal caso, se l’eccezione viene lanciata, il
metodo termina
Linguaggi di Programmazione II
2003-04
36
18
Segnalare eccezioni
„
Non gestire le eccezioni non significa
essere irresponsabili
„
E’ meglio non gestirle, quando non si sa
come gestirle!
Linguaggi di Programmazione II
2003-04
37
Segnalare eccezioni
public class Coin
{
public void read(BufferedReader in) throws
IOException
{
value = Double.parseDouble(in.readLine());
name =in.readLine();
}
...
}
Linguaggi di Programmazione II
2003-04
38
19
Segnalare eccezioni
„
Qualunque metodo che chiama Coin.read deve
decidere se gestire l’eccezione o dichiarare se
poterla lanciare
public class Purse
{
public void read(BufferedReader in) throws
IOException
{
while (…)
{ Coin c = new Coin();
c.read(in);
add©;
}
}
...
Linguaggi di Programmazione II
2003-04
}
39
Segnalare eccezioni
„
Un metodo può lanciare più eccezioni
controllate, di tipo diverso
public void read(BufferedReader in)
throws IOException, ClassNotFoundException
Linguaggi di Programmazione II
2003-04
40
20
Sintassi: segnalare un’eccezione
specificatoreDiAccesso valoreRestituito nomeMetodo
(tipoParametro nomeParametro, . . .)
throws ClasseEccezione, ClasseEccezione . .
Esempio:
public void read(BufferedReader in) throws
IOException
Scopo:
Segnalare le eccezioni controllate che possono
essere lanciate dal metodo
Linguaggi di Programmazione II
2003-04
41
Progettare eccezioni
ƒA volte nessun tipo di eccezione standard va
bene per la nostra condizione di errore
ƒIn tal caso possiamo progettare una nuova
classe di eccezioni
ƒPoi dobbiamo decidere se deve essere
controllata oppure no
Linguaggi di Programmazione II
2003-04
42
21
Progettare eccezioni
ƒBisogna controllare che amount <= account.getBalance()
prima di invocare withdraw
ƒNecessaria una eccezione non controllata
ƒSottoclasse di RunTimeException
if (amount > balance)
{
throw new InsufficientFundsException(
“withdrawal of” + amount +
“ exceeds balance of ” + balance);
}
Linguaggi di Programmazione II
2003-04
43
Progettare eccezioni
ƒLa nuova classe di eccezioni ha due costruttori
ƒUno senza argomenti
ƒUno che ha come parametro la stringa che descrive il
motivo dell’eccezione
public class InsufficientFundsException
extends RuntimeException
{
public InsufficientFundsException()
{
}
public InsufficientFundsException(String reason)
{
super(reason);
}
}
Linguaggi di Programmazione II
2003-04
44
22
Catturare eccezioni
ƒ Ogni eccezione deve essere gestita,
altrimenti causa l’arresto del programma
ƒ Per installare un gestore si usa l’enunciato
try, seguito da tante clausole catch
quante sono le eccezioni da gestire
Linguaggi di Programmazione II
2003-04
try
{
45
Catturare eccezioni
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("How old are you?");
String inputLine = in.readLine();
int age = Integer.parseInt(inputLine);
age++;
System.out.println("Next year,you'll be " + age);
}
catch (IOException exception)
{
System.out.println("Input/output error “
+exception);
}
catch (NumberFormatException exception)
{
System.out.println("Input was not a number");
Linguaggi di Programmazione II
}
46
2003-04
23
Catturare eccezioni
ƒ
Vengono eseguite le istruzioni all’interno del
blocco try
ƒ
Se nessuna eccezione viene lanciata, le
clausole catch sono ignorate
ƒ
Se viene lanciata una eccezione di tipo
IOException o NumberFormatException, viene
eseguita la clausola catch corrispondente
Linguaggi di Programmazione II
2003-04
try
{
47
Sintassi: Blocco Try generico
enunciato
enunciato
...
}
catch (ClasseEccezione oggettoEccezione)
{
enunciato
enunciato
...
}
catch (ClasseEccezione oggettoEccezione)
{
enunciato
enunciato
...
}
...
Linguaggi di Programmazione II
2003-04
48
24
Esempio:
try
{
System.out.println("What is your name?");
String name = console.readLine();
System.out.println("Hello,"+name +"!");
}
catch (IOException exception)
{
exception.printStackTrace();
System.exit(1);
}
Scopo:
Eseguire uno o più enunciati che possono lanciare eccezioni.
Linguaggi di Programmazione II
2003-04
49
La clausola finally
„
„
Il lancio di un’eccezione arresta il metodo corrente
A volte vogliamo eseguire altre istruzioni prima
dell’arresto
‰
Esempio:
BufferedReader in;
in = new BufferedReader(new FileReader(filename));
purse.read(in);
in.close();
„
„
Vogliamo eseguire in.close() anche se viene
lanciata un’eccezione!
La clausola finally viene usata per indicare
un’istruzione che va eseguita sempre
Linguaggi di Programmazione II
2003-04
50
25
La clausola finally
BufferedReader in;
try
{
in = new BufferedReader(
new FileReader(filename));
purse.read(in);
}
finally
{
if (in !=null) in.close();
}
Linguaggi di Programmazione II
2003-04
51
La clausola finally
ƒ Viene
eseguita al termine del blocco try
ƒ Viene
comunque eseguita se
un’istruzione del blocco try lancia
un’eccezione
ƒ Può
anche essere combinata con
clausole catch
Linguaggi di Programmazione II
2003-04
52
26
Sintassi: la clausola finally
try
{
enunciato
enunciato
...
}
finally
{
enunciato
enunciato
...
}
Linguaggi di Programmazione II
2003-04
53
Un esempio completo
„
Scriviamo un programma che
o Chiede all’utente il nome di un file
o Legge una sequenza di descrizioni di monete dal file
o Aggiunge le monete a un borsellino
o Stampa il contenuto totale del borsellino
„
Cosa può andare storto?
o Il file potrebbe non esistere
o I dati nel file potrebbero essere nel formato errato
„
Chi può individuare gli errori?
o Il metodo main interagisce con l’utente e dovrebbe
catturare qualsiasi eccezione
Linguaggi di Programmazione II
2003-04
54
27
Il metodo read della classe Coin
Non gestisce le eccezioni, ma le passa al chiamante
public boolean read(BufferedReader in) throws
IOException
{
String input =in.readLine();
if (input == null) // fine attesa del file
return false;
value = Double.parseDouble(input);
name = in.readLine();
if (name == null) // fine inattesa del file
throw new EOFException("Coin name expected");
return true;
}
Linguaggi di Programmazione II
2003-04
55
Il metodo read della classe Purse
public void read(BufferedReader in) throws
IOException
{
boolean done = false;
while (!done)
{
Coin c = new Coin();
if (c.read(in)) add(c);
else done =true;
}
}
Linguaggi di Programmazione II
2003-04
56
28
Il metodo readFile della classe Purse
La clausola
finally
chiude il file se viene lanciata una eccezione
public void readFile(String filename) throws
IOException
{
BufferedReader in = null;
try
{
in = new BufferedReader(
new FileReader(filename));
read(in);
}
finally
{
if (in != null)
in.close();
Linguaggi di Programmazione II
}
2003-04
}
57
Interazione con l’utente nel main
In caso di un’eccezione, l’utente può specificare il nome di un altro file
boolean done = false;
String filename =
JOptionPane.showInputDialog("Enter
file name");
while (!done)
{
try
{
Purse myPurse = new Purse();
myPurse.readFile(filename);
System.out.println("total=" +
myPurse.getTotal());
done =true;
}
Linguaggi di Programmazione II
2003-04
58
29
catch (IOException exception)
{
System.out.println("Input/output error " +
exception);
}
catch (NumberFormatException exception)
{
exception.printStackTrace(); // error in file
format
}
if (!done)
{
Filename = JOptionPane.showInputDialog("Try
another file:");
if (filename == null)
done =true;
}
}
Linguaggi di Programmazione II
2003-04
59
Riepilogo
1.
2.
3.
4.
5.
6.
7.
8.
chiama Purse.readFile
Purse.readFile chiama Purse.read
Purse.read chiama Coin.read
Coin.read lancia una EOFException
Coin.read non gestisce l’eccezione e termina la sua
esecuzione
Purse.read non gestisce l’eccezione e termina la sua
esecuzione
Purse.readFile non gestisce l’eccezione e termina la sua
esecuzione, dopo aver chiuso il file
PurseTest.main ha un gestore per le eccezioni di tipo
IOException. Tale gestore stampa un messaggio per l’utente
e gli dà la possibilità di scegliere un altro file
PurseTest.main
Linguaggi di Programmazione II
2003-04
60
30
File PurseTest.java
import javax.swing.JOptionPane;
import java.io.IOException;
/**
Questo programma chiede all’utente di inserire il nome di un
file contenente descrizioni di monete. Un oggetto di tipo Purse
viene riempito con le monete specificate nel file.In caso venga
lanciata un’eccezione, l’utente può scegliere un altro file.
*/
public class PurseTest
{
public static void main(String[] args)
{
boolean done = false;
String filename
= JOptionPane.showInputDialog("Enter file name");
Linguaggi di Programmazione II
2003-04
61
while (!done)
{
try
{
Purse myPurse = new Purse();
myPurse.readFile(filename);
System.out.println("total="
+ myPurse.getTotal());
done = true;
}
catch (IOException exception)
{
System.out.println("Input/output error "
+ exception);
}
catch (NumberFormatException exception)
{
exception.printStackTrace();
}
Linguaggi di Programmazione II
2003-04
62
31
if (!done)
{
filename = JOptionPane.showInputDialog(
"Try another file:");
if (filename == null) done = true;
}
}
System.exit(0);
}
}
Linguaggi di Programmazione II
2003-04
63
File Purse.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
Un borsellino calcola il totale di un insieme di
monete.
*/
public class Purse
{
/**
Costruisce un borsellino vuoto.
*/
public Purse()
{
total = 0;
}
Linguaggi di Programmazione II
2003-04
64
32
/**
Legge un file con descrizioni di monete e
aggiunge le monete al borsellino.
@param filename il nome del file
*/
public void readFile(String filename)
throws IOException
{
BufferedReader in = null;
try
{
in = new BufferedReader(
new FileReader(filename));
read(in);
}
finally
{
if (in != null) in.close();
}
}
Linguaggi di Programmazione II
2003-04
65
/**
Legge un file con descrizioni di monete e
aggiunge le monete al borsellino.
@param in il lettore con buffer da cui leggere
*/
public void read(BufferedReader in)
throws IOException
{
boolean done = false;
while (!done)
{
Coin c = new Coin();
if (c.read(in))
add(c);
else
done = true;
}
}
Linguaggi di Programmazione II
2003-04
66
33
/**
Aggiunge una moneta al borsellino.
@param aCoin la moneta da aggiungere
*/
public void add(Coin aCoin)
{
total = total + aCoin.getValue();
}
/**
Restituisce il valore totale delle monete
nel borsellino.
@return la somma dei valori di tutte le monete
*/
public double getTotal()
{
return total;
}
private double total;
}
Linguaggi di Programmazione II
2003-04
67
File Coin.java
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
/**
Una moneta con un valore.
*/
public class Coin
{
/**
Costruisce una moneta predefinita.
Usa il metodo read per inizializzarne i campi.
*/
public Coin()
{
value = 0;
name = "";
Linguaggi di Programmazione II
}
2003-04
68
34
/**
Costruisce una moneta.
@param aValue il valore monetario della moneta
@param aName il nome della moneta
*/
public Coin(double aValue, String aName)
{
value = aValue;
name = aName;
}
/**
Legge il valore e il nome di una moneta.
@param in il lettore
@return true se i dati sono stati letti,
false se si è raggiunta la fine del flusso
*/
public boolean read(BufferedReader in)
Linguaggi di Programmazione II
2003-04
69
throws IOException
{
String input = in.readLine();
if (input == null) return false;
value = Double.parseDouble(input);
name = in.readLine();
if (name == null)
throw new EOFException("Coin name expected");
return true;
}
/**
Restituisce il valore della moneta.
@return il valore
*/
public double getValue()
{
return value;
}
Linguaggi di Programmazione II
2003-04
70
35
/**
Restituisce il nome della moneta.
@return il nome
*/
public String getName()
{
return name;
}
private double value;
private String name;
}
Linguaggi di Programmazione II
2003-04
71
Cifratura simmetrica
Alice
canale insicuro
Linguaggi di Programmazione II
2003-04
Bob
72
36
Cifratura simmetrica
Algoritmo di
decifratura
m
m
Alice
canale insicuro
Algoritmo di
cifratura
Bob
Linguaggi di Programmazione II
2003-04
73
Cifrari simmetrici
chiave privata k
chiave privata k
C ← CIFRA(k,M)
CIFRA
M ← DECIFRA(k,C)
DECIFRA
C
Alice
canale insicuro
Bob
messaggio M
Linguaggi di Programmazione II
2003-04
74
37
Cifrario di Cesare
100100-44 a.C.
Svetonio (Vitae Caesarorum): lettera di Cesare a Cicerone
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
testo in chiaro
X ← M+3 mod 26
OMNIA GALLIA EST DIVISA IN PARTES TRES
RPQLD JDOOLD HVW GLYLVD LQ SDUWHV WUHV
testo cifrato
Linguaggi di Programmazione II
2003-04
75
Cifrari con shift
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Chiave K
X ← M+K mod 26
K∈{0,1,…,25}
Linguaggi di Programmazione II
2003-04
76
38
Cifratura di dati binari
ƒ
Scriviamo un programma che
ƒ
ƒ
ƒ
Legge da un file dati binari, un byte alla volta
Cifra i dati, un byte alla volta, usando un
cifrario con shift
Scrive in un file i byte cifrati, uno alla volta
Linguaggi di Programmazione II
2003-04
77
Cifratura di dati binari
int next = in.read(); //leggi il prossimo byte
if (next == -1)
done = true;
else //il file non è terminato
{
byte b = (byte)next; //converti in byte
byte c = encrypt(b); //cifra il byte
out.write(c); //stampa il byte cifrato
}
Linguaggi di Programmazione II
2003-04
78
39
File Encryptor.java
import
import
import
import
import
import
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.InputStream;
java.io.OutputStream;
java.io.IOException;
public class Encryptor
{
/**
Costruisce un cifratore.
@param aKey la chiave di cifratura
public Encryptor(int aKey)
{
key = aKey;
}
Linguaggi di Programmazione II
2003-04
79
/**
Cifra il contenuto di un file.
@param inFile il file di ingresso
@param outFile il file di uscita
*/
public void encryptFile(File inFile, File outFile)
throws IOException
{
InputStream in = null;
OutputStream out = null;
try
{
in = new FileInputStream(inFile);
out = new FileOutputStream(outFile);
encryptStream(in, out);
}
finally
{
if (in != null) in.close();
if (out != null) out.close();
}
}
Linguaggi di Programmazione II
2003-04
80
40
/**
Cifra il contenuto di un flusso.
@param in il flusso di ingresso
@param out il flusso di uscita
*/
public void encryptStream(InputStream in, OutputStream out)
throws IOException
{
boolean done = false;
while (!done)
{
int next = in.read();
if (next == -1) done = true;
else
{
byte b = (byte)next;
byte c = encrypt(b);
out.write(c);
}
}
}
Linguaggi di Programmazione II
2003-04
81
/**
Cifra un byte.
@param b il byte da cifrare
@return il byte cifrato
*/
public byte encrypt(byte b)
{
return (byte)(b + key);
}
private int key;
}
Linguaggi di Programmazione II
2003-04
82
41
File EncryptorTest.java
import
import
import
import
java.io.File;
java.io.IOException;
javax.swing.JFileChooser;
javax.swing.JOptionPane;
/**
Un programma per collaudare il cifratore
*/
public class EncryptorTest
{
public static void main(String[] args)
{
try
{
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null)
!= JFileChooser.APPROVE_OPTION)
System.exit(0);
Linguaggi di Programmazione II
2003-04
83
File inFile = chooser.getSelectedFile();
if (chooser.showSaveDialog(null)
!= JFileChooser.APPROVE_OPTION)
System.exit(0);
File outFile = chooser.getSelectedFile();
String input =
JOptionPane.showInputDialog("Key");
int key = Integer.parseInt(input);
Encryptor crypt = new Encryptor(key);
crypt.encryptFile(inFile, outFile);
}
catch (NumberFormatException exception)
{
System.out.println("Key must be an integer: "
+ exception);
}
catch (IOException exception)
{
System.out.println("Error processing file: "
+ exception);
}
System.exit(0);
}
}
84
42
Argomenti sulla riga di comando
ƒ
ƒ
Spesso eseguiamo un programma
dalla riga di comando
Possiamo anche passare delle
informazioni (stringhe) aggiuntive
ƒ
ƒ
Argomenti sulla riga di comando
Memorizzati all’interno dell’ array di
stringhe args, parametro del metodo main
Linguaggi di Programmazione II
2003-04
85
Esempio
‰
Java MyProgram -d file.txt
class MyProgram
{
public static void main(String[] args)
{
...
}
args[0] "-d"
}
args[1]
Linguaggi di Programmazione II
2003-04
"file.txt"
86
43
Argomenti sulla riga di comando
ƒ
Scriviamo un programma che testa
la classe Encryptor
ƒ
Legge il nome del file da cifrare e la
chiave di cifratura dalla riga di comando
Linguaggi di Programmazione II
2003-04
87
Argomenti sulla riga di comando
ƒ
Argomenti accettati
ƒ
-d per indicare la decifratura
ƒ -k per indicare la chiave (3 di default)
ƒ Il nome del file input
ƒ Il nome del file output
Esempio:
ƒ
ƒ
java Crypt input.txt encrypt.txt
ƒ
java Crypt –d –k11 encrypt.txt output.txt
Linguaggi di Programmazione II
2003-04
88
44
File Crypt.java
import java.io.File;
import java.io.IOException;
public class Crypt
{
public static void main(String[] args)
{
boolean decrypt = false;
int key = DEFAULT_KEY;
File inFile = null;
File outFile = null;
if (args.length < 2 || args.length > 4) usage();
Linguaggi di Programmazione II
2003-04
89
try
{
for (int i = 0; i < args.length; i++)
{
if (args[i].charAt(0) == '-')
{
// è un’opzione della riga comandi
char option = args[i].charAt(1);
if (option == 'd')
decrypt = true;
else if (option == 'k')
key = Integer.parseInt(
args[i].substring(2));
}
Linguaggi di Programmazione II
2003-04
90
45
else
{
// è il nome di un file
if (inFile == null)
inFile = new File(args[i]);
else if (outFile == null)
outFile = new File(args[i]);
else usage();
}
}
if (decrypt) key = -key;
Encryptor crypt = new Encryptor(key);
crypt.encryptFile(inFile, outFile);
}
catch (NumberFormatException exception)
{
System.out.println("Key must be an integer: "
+ exception);
}
Linguaggi di Programmazione II
2003-04
91
catch (IOException exception)
{
System.out.println("Error processing file: "
+ exception);
}
}
/**
Stampa un messaggio che descrive l’uso corretto,
poi termina il programma.
*/
public static void usage()
{
System.out.println(
"Usage: java Crypt [–d] [–kn] infile outfile");
System.exit(1);
}
public static final int DEFAULT_KEY = 3;
}
Linguaggi di Programmazione II
2003-04
92
46
Scrittura di Oggetti su file
ƒ
Per scrivere un oggetto su file
ƒ
ƒ
ƒ
Si individuano le caratteristiche
dell’oggetto
Si codificano tali caratteristiche (con
stringhe o numeri)
Si memorizzano le caratteristiche
separatamente
Linguaggi di Programmazione II
2003-04
93
Lettura di Oggetti da file
ƒ
Per leggere un oggetto da file
ƒ
ƒ
Si leggono le caratteristiche codificate
separatamente dal file
Si organizzano tali caratteristiche in un
oggetto
Linguaggi di Programmazione II
2003-04
94
47
Esempio
Per salvare un oggetto Rectangle
ƒ
Si individua l’altezza
Si individua la larghezza
Si memorizzano I valori separatamente
ƒ
ƒ
ƒ
Per leggere un oggetto Rectangle
ƒ
Si legge l’altezza dal file
Si legge la larghezza dal file
Si crea un oggetto Rectangle con tali valori
ƒ
ƒ
ƒ
Linguaggi di Programmazione II
2003-04
95
Lettura di Oggetti da file
ƒ
Esistono classi che permettono di
ƒ
ƒ
Scrivere interi oggetti su file
ƒ Flussi di oggetti in scrittura
ƒ Classe ObjectOutputStream
Leggere interi oggetti da file
ƒ Flussi di oggetti in lettura
ƒ Classe ObjectInputStream
Linguaggi di Programmazione II
2003-04
96
48
Vantaggi
ƒ
Per scrivere un intero oggetto
ƒ
ƒ
ƒ
Non dobbiamo prima decomporlo in altra forma
Possiamo fare una sola operazione!
Per leggere un intero oggetto
ƒ
ƒ
Non dobbiamo leggere i dati separatamente e poi
ricomporre l’oggetto
Possiamo fare una sola operazione!
Linguaggi di Programmazione II
2003-04
97
Serializzazione
ƒ
La memorizzazione di oggetti in un flusso
viene detta serializzazione
ƒ
ƒ
ƒ
Ogni oggetto riceve un numero di serie
Se lo stesso oggetto viene salvato due volte la
seconda volta salviamo solo il numero di serie
Due numeri di serie uguali sono interpretati come
riferimenti allo stesso oggetto
Linguaggi di Programmazione II
2003-04
98
49
Serializzazione
ƒ
L’oggetto da inserire nel flusso deve
essere serializzabile
ƒ
Appartenere a una classe che implementa
l’interfaccia Serializable
ƒ Non ha metodi
Linguaggi di Programmazione II
2003-04
99
Serializzazione
„
Per scrivere oggetti di una classe
MyClass che implementa
Serializable in un flusso di oggetti
MyClass mc = new ……
ObjectOutputStream out = new
ObjectOutputStream(new
FileOutputStream(“mc.dat”));
out.writeObject(mc);
Linguaggi di Programmazione II
2003-04
100
50
Serializzazione
Per leggere oggetti di una classe
MyClass che implementa
Serializable da un flusso di oggetti
„
ObjectInputStream in = new
ObjectInputStream(new
FileInputStream(“mc.dat”));
MyClass mc =
(MyClass)in.readObject();
Linguaggi di Programmazione II
2003-04
101
Serializzazione: readObject
ƒ
ƒ
ƒ
Legge un Object da file
Restituisce un riferimento a tale Object
L’output necessita di un cast
MyClass mc = (MyClass) in.readObject();
ƒ
Può lanciare un’eccezione controllata di tipo
ClassCastException
ƒ
Da catturare o dichiarare in una clausola
throws
Linguaggi di Programmazione II
2003-04
102
51
Serializzazione
ƒ
ƒ
La serializzazione non riguarda solo
oggetti semplici
Ogni oggetto è serializzabile se
ottenuto da una classe che
implementa Serializable
Linguaggi di Programmazione II
2003-04
103
Serializzazione: esempio
„
Vediamo un programma che
‰
‰
‰
‰
‰
Legge un borsellino da un file se tale file
esiste
Crea un borsellino nuovo se il file non esiste
Aggiunge delle monete al borsellino
Scrive il borsellino sul file creandolo se non
esiste
Usa le classi Purse e Coin già viste con la
differenza che
„
„
Generano oggetti serializzabili
Implementano l’interfaccia Serializable
Linguaggi di Programmazione II
2003-04
104
52
File PurseTest.java
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JOptionPane;
Linguaggi di Programmazione II
2003-04
105
Public class PurseTest
{
public static void main(String[] args)
throws IOException,
ClassNotFoundException
{
Purse MyPurse;
File f = new File(“purse.dat”);
if (f.esists())
{
ObjectInputStream in = new ObjectInputStream(
new FileInputStream(f));
myPurse = (Purse)in.readObject();
in.close();
}
Linguaggi di Programmazione II
2003-04
106
53
else myPurse = new Purse();
//Aggiungi le monete al borsellino
myPurse.add(new Coin(NICKEL_VALUE,”nickel”));
myPurse.add(new Coin(DIME_VALUE,”dime”));
myPurse.add(new Coin(QUARTER_VALUE,”quarter”));
double totalValue = myPurse.getTotal();
System.out.println(“The total is “ + totalValue);
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream(f));
out.writeObject(myPurse);
out.close();
}
Linguaggi di Programmazione II
2003-04
107
private static final double NICKEL_VALUE = 0.05;
private static final double DIME_VALUE = 0.1;
private static final double QUARTE_VALUE = 0.25;
}
Linguaggi di Programmazione II
2003-04
108
54
Accesso sequenziale e casuale
ƒ Accesso sequenziale
ƒ Un file viene elaborato un byte alla
volta
ƒ Accesso casuale
ƒ Possiamo accedere a posizioni
arbitrarie nel file
Linguaggi di Programmazione II
2003-04
109
Accesso sequenziale
ƒ Ogni file su disco ha un puntatore
del file posto alla fine del file
ƒ Qualsiasi dato viene aggiunto alla
fine del file
ƒ Se il puntatore viene spostato i dati
sono sovrascritti
Linguaggi di Programmazione II
2003-04
110
55
Accesso casuale
ƒ Per spostare il puntatore del file,
usiamo un oggetto di tipo
RandomAccessFile
ƒ Specificando se il file deve essere aperto il
lettura (“r”) o anche in scrittura (“rw”)
RandomAccessFile f = new
RandomAccessFile("bank.dat","rw");
Linguaggi di Programmazione II
2003-04
111
Accesso casuale
ƒ Spostiamo il puntatore del file con
il metodo seek
ƒ f.seek(n);
ƒ sposta il puntatore al byte in posizione n
ƒ n = f.getFilePointer();
ƒ Fornisce la posizione corrente del puntatore del
file
ƒ filelength = f.length();
ƒ Fornisce il numero di byte del file
Linguaggi di Programmazione II
2003-04
112
56
Accesso sequenziale e casuale
Pochè i file possono essre molto
grandi, i valori del puntatore del file
sono dei long
Linguaggi di Programmazione II
2003-04
113
57