Lavorare con i File e gestire le Eccezioni

Due modi per memorizzare i dati
Lavorare con i File e gestire
le Eccezioni
„
Formato testo
Dati rappresentati come sequenze di
caratteri
‰ 12345 memorizzato come ‘1’ ‘2’ ‘3’ ‘4’ ‘5’
‰
Anno Accademico 2003/04
„
Formato binario
Dati rappresentati come sequenze di
byte
‰ 12345 memorizzato come 00 00 48 57
Docente modulo 2: Barbara Masucci
‰
Linguaggi di Programmazione II
2003-04
Leggere dati da un file
Elaborare dati in ingresso e in
uscita
„
„
ƒ Per dati di testo, creare un oggetto di
tipo FileReader
Formato testo
‰
ƒ FileReader reader = new
Usare le classi Reader e Writer e le
loro sottoclassi
FileReader("in.txt");
Formato binario
‰
2
ƒ Per dati binari, creare un oggetto di
tipo FileInputStream
Usare le classi InputStream e
OutputStream e le loro sottoclassi
ƒ FileInputStream inputStream = new
FileInputStream("in.dat");
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
3
Scrivere dati in un file
4
Dove sono tutte queste classi?
ƒ Per dati di testo, creare un oggetto di
tipo FileWriter
ƒ FileWriter writer = new
ƒ Le classi
ƒ FileReader, FileWriter,
FileInputStream, FileOutputStream
sono nel package java.io
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
Linguaggi di Programmazione II
2003-04
6
1
Leggere dati di testo da un file
Leggere dati di testo da un file
FileReader reader = new FileReader("in.txt");
ƒ Il metodo read della classe Reader
legge un carattere alla volta
//legge il prossimo carattere
int next = reader.read();
char c;
ƒ restituisce un int che rappresenta il
carattere letto (va convertito in un
char)
ƒ restituisce -1 se il file è terminato
//se il file non è terminato fai il cast a char
if (next != -1)
c = (char)next;
ƒ Alla fine bisogna chiudere il file
Linguaggi di Programmazione II
2003-04
//chiudi il file
reader.close()
7
Linguaggi di Programmazione II
2003-04
8
Leggere dati binari da un file
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
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
9
10
Scrivere dati binari in un file
Scrivere dati di testo in un file
ƒIl metodo write della classe Writer scrive
un carattere alla volta
ƒ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();
FileWriter writer = new
FileWriter("out.txt");
...
char c='';
...
writer.write(c); ...
write.close();
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
11
Linguaggi di Programmazione II
2003-04
12
2
Scrivere file di testo
Errori comuni
ƒ Usiamo un oggetto di tipo PrintWriter
per
ƒ Quando si digita il path di un file ogni
barra rovesciata va inserita due volte
ƒ Spezzare numeri e stringhe in singoli
caratteri
ƒ Inviarli uno alla volta a un oggetto di tipo
ƒ Una singola barra rovesciata è un carattere
speciale!
FileWriter
FileReader reader = new
FileReader(“C:\\nomedir\\nomefile.txt");
FileWriter writer = new FileWriter(“out.txt”);
PrintWriter out = new PrintWriter(writer);
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
13
Scrivere file di testo
Scrivere file di testo
Possiamo usare i metodi print e println
della classe PrintWriter per stampare
numeri, oggetti e stringhe
I metodi print e println
ƒ
ƒ
out.println(29.95);
ƒ
15
Leggere file di testo
Linguaggi di Programmazione II
2003-04
16
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
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
out.println(new Rectangle(5,10,15,25));
out.println("Hello, World!");
Linguaggi di Programmazione II
2003-04
14
17
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
3
La classe File
La classe File: alcuni metodi
ƒ
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
ƒ
ƒ
„ delete
-Cancella il file
„ renameTo
-Rinomina il file
„ exists
-Restituisce true se il file esiste già
FileReader reader = new FileReader(inputFile);
Linguaggi di Programmazione II
2003-04
19
Finestre per la selezione di file
ƒ
ƒ
Linguaggi di Programmazione II
2003-04
20
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
Linguaggi di Programmazione II
2003-04
Finestre per la selezione di file
Finestre per la selezione di file
I metodi invocati restituiscono
//crea la finestra di dialogo
JFileChooser chooser new JFileChooser();
FileReader in = null;
ƒ
JFileChooser.APPROVE_OPTION
se l’utente sceglie
22
un file
ƒ
JFileChooser.CANCEL_OPTION
//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);
}
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
Linguaggi di Programmazione II
2003-04
24
4
Eccezioni
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
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
25
Sintassi: lanciare un’eccezione
26
Esempio
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
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
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
Gerarchia delle
classi di eccezioni
Linguaggi di Programmazione II
2003-04
ƒ dovute a circostanze che il programmatore
può evitare
29
Linguaggi di Programmazione II
2003-04
30
5
Tipi di eccezioni
Tipi di eccezioni
ƒ Esempio di eccezione controllata
ƒ Esempio di eccezione non controllata
ƒ EOFException: terminazione inaspettata del
flusso di dati in ingresso
ƒ Può essere provocata da eventi esterni
ƒ 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
ƒ errore del disco
ƒ interruzione del collegamento di rete
ƒ Il gestore dell’eccezione si occupa del
problema
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
31
Eccezioni controllate
Eccezioni non controllate
ƒ Tutte le sottoclassi di IOException
ƒ
ƒ
ƒ
ƒ
ƒ Tutte le sottoclassi di RunTimeException
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
EOFException
FileNotFoundException
MalformedURLException
UnknownHostException
ƒ ClassNotFoundException
ƒ CloneNotSupportedException
Linguaggi di Programmazione II
2003-04
32
ArithmeticException
ClassCastException
IllegalArgumentException
IllegalStateException
IndexOutOfBoundsException
NoSuchElementException
NullPointerException
Linguaggi di Programmazione II
2003-04
33
Eccezioni controllate e non controllate
34
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
‰
„
Linguaggi di Programmazione II
2003-04
35
In tal caso, se l’eccezione viene lanciata, il
metodo termina
Linguaggi di Programmazione II
2003-04
36
6
Segnalare eccezioni
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
public class Coin
{
public void read(BufferedReader in) throws
IOException
{
value = Double.parseDouble(in.readLine());
name =in.readLine();
}
...
}
Linguaggi di Programmazione II
2003-04
37
Segnalare eccezioni
„
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
}
38
„
Un metodo può lanciare più eccezioni
controllate, di tipo diverso
public void read(BufferedReader in)
throws IOException, ClassNotFoundException
39
Linguaggi di Programmazione II
2003-04
40
Progettare eccezioni
Sintassi: segnalare un’eccezione
ƒ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
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
Linguaggi di Programmazione II
2003-04
42
7
Progettare eccezioni
Progettare eccezioni
ƒBisogna controllare che amount <= account.getBalance()
prima di invocare withdraw
ƒNecessaria una eccezione non controllata
ƒLa nuova classe di eccezioni ha due costruttori
ƒUno senza argomenti
ƒUno che ha come parametro la stringa che descrive il
motivo dell’eccezione
ƒSottoclasse di RunTimeException
public class InsufficientFundsException
extends RuntimeException
{
public InsufficientFundsException()
{
}
if (amount > balance)
{
throw new InsufficientFundsException(
“withdrawal of” + amount +
“ exceeds balance of ” + balance);
}
Linguaggi di Programmazione II
2003-04
public InsufficientFundsException(String reason)
{
super(reason);
}
}
Catturare eccezioni
try
{
ƒ 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
Linguaggi di Programmazione II
2003-04
43
45
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
44
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
}
2003-04
try
{
46
Sintassi: Blocco Try generico
enunciato
enunciato
...
}
catch (ClasseEccezione oggettoEccezione)
{
enunciato
enunciato
...
}
catch (ClasseEccezione oggettoEccezione)
{
enunciato
enunciato
Linguaggi di Programmazione II
2003-04
47
...
}
...
Linguaggi di Programmazione II
2003-04
48
8
La clausola finally
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);
}
„
„
‰
„
Eseguire uno o più enunciati che possono lanciare eccezioni.
„
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
49
La clausola finally
50
La clausola finally
ƒ Viene
BufferedReader in;
try
{
in = new BufferedReader(
new FileReader(filename));
purse.read(in);
}
finally
{
if (in !=null) in.close();
}
Linguaggi di Programmazione II
2003-04
Esempio:
BufferedReader in;
in = new BufferedReader(new FileReader(filename));
purse.read(in);
in.close();
Scopo:
Linguaggi di Programmazione II
2003-04
Il lancio di un’eccezione arresta il metodo corrente
A volte vogliamo eseguire altre istruzioni prima
dell’arresto
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
51
52
Un esempio completo
Sintassi: la clausola finally
try
{
„
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
enunciato
enunciato
...
}
finally
{
enunciato
enunciato
...
}
Linguaggi di Programmazione II
2003-04
53
Linguaggi di Programmazione II
2003-04
54
9
Il metodo read della classe Purse
Il metodo read della classe Coin
Non gestisce le eccezioni, ma le passa al chiamante
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;
}
}
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
Linguaggi di Programmazione II
2003-04
55
Il metodo readFile della classe Purse
La clausola
finally
56
Interazione con l’utente nel main
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
}
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;
}
58
Riepilogo
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
Linguaggi di Programmazione II
2003-04
57
1.
2.
3.
4.
5.
6.
7.
8.
59
chiama 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
Purse.readFile
Linguaggi di Programmazione II
2003-04
60
10
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
File Purse.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
if (!done)
{
filename = JOptionPane.showInputDialog(
"Try another file:");
if (filename == null) done = true;
/**
Un borsellino calcola il totale di un insieme di
monete.
*/
public class Purse
{
/**
Costruisce un borsellino vuoto.
*/
public Purse()
{
total = 0;
}
}
}
System.exit(0);
}
}
Linguaggi di Programmazione II
2003-04
63
/**
64
/**
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;
}
}
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
Linguaggi di Programmazione II
2003-04
65
Linguaggi di Programmazione II
2003-04
66
11
File Coin.java
/**
Aggiunge una moneta al borsellino.
@param aCoin la moneta da aggiungere
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
*/
public void add(Coin aCoin)
{
total = total + aCoin.getValue();
}
/**
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
}
/**
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
68
2003-04
/**
throws IOException
Costruisce una moneta.
@param aValue il valore monetario della moneta
@param aName il nome della moneta
{
String input = in.readLine();
if (input == null) return false;
*/
public Coin(double aValue, String aName)
{
value = aValue;
value = Double.parseDouble(input);
name = in.readLine();
if (name == null)
throw new EOFException("Coin name expected");
return true;
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
/**
Restituisce il valore della moneta.
@return il valore
*/
public double getValue()
{
return value;
}
Linguaggi di Programmazione II
2003-04
69
70
Cifratura simmetrica
/**
Restituisce il nome della moneta.
@return il nome
*/
public String getName()
{
return name;
}
private double value;
private String name;
Alice
}
canale insicuro
Linguaggi di Programmazione II
2003-04
71
Linguaggi di Programmazione II
2003-04
Bob
72
12
Cifrari simmetrici
Cifratura simmetrica
Algoritmo di
decifratura
m
chiave privata k
chiave privata k
C ← CIFRA(k,M)
CIFRA
m
M ← DECIFRA(k,C)
DECIFRA
C
Alice
canale insicuro
Algoritmo di
cifratura
canale insicuro
Alice
Bob
messaggio M
Linguaggi di Programmazione II
2003-04
Bob
73
Cifrario di Cesare
Linguaggi di Programmazione II
2003-04
74
Cifrari con shift
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
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
Chiave K
X ← M+3 mod 26
X ← M+K mod 26
K∈{0,1,…,25}
OMNIA GALLIA EST DIVISA IN PARTES TRES
RPQLD JDOOLD HVW GLYLVD LQ SDUWHV WUHV
testo cifrato
Linguaggi di Programmazione II
2003-04
75
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
}
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
76
Cifratura di dati binari
Scriviamo un programma che
ƒ
Linguaggi di Programmazione II
2003-04
77
Linguaggi di Programmazione II
2003-04
78
13
/**
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;
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;
try
{
in = new FileInputStream(inFile);
out = new FileOutputStream(outFile);
encryptStream(in, out);
}
finally
{
if (in != null) in.close();
if (out != null) out.close();
}
public class Encryptor
{
/**
Costruisce un cifratore.
@param aKey la chiave di cifratura
public Encryptor(int aKey)
{
key = aKey;
}
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
}
79
80
/**
Cifra il contenuto di un flusso.
@param in il flusso di ingresso
@param out il flusso di uscita
/**
Cifra un byte.
@param b il byte da cifrare
@return il byte cifrato
*/
*/
public void encryptStream(InputStream in, OutputStream out)
throws IOException
{
public byte encrypt(byte b)
{
return (byte)(b + key);
}
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);
}
}
private int key;
}
}
Linguaggi di Programmazione II
2003-04
Linguaggi di Programmazione II
2003-04
81
File EncryptorTest.java
import
import
import
import
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);
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
82
}
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);
83
}
}
84
14
Argomenti sulla riga di comando
ƒ
ƒ
Esempio
‰
Spesso eseguiamo un programma
dalla riga di comando
Possiamo anche passare delle
informazioni (stringhe) aggiuntive
ƒ
ƒ
class MyProgram
{
public static void main(String[] args)
{
...
}
args[0] "-d"
}
Argomenti sulla riga di comando
Memorizzati all’interno dell’ array di
stringhe args, parametro del metodo main
Linguaggi di Programmazione II
2003-04
args[1]
ƒ
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:
ƒ
Legge il nome del file da cifrare e la
chiave di cifratura dalla riga di comando
Linguaggi di Programmazione II
2003-04
86
Argomenti sulla riga di comando
Scriviamo un programma che testa
la classe Encryptor
ƒ
"file.txt"
Linguaggi di Programmazione II
2003-04
85
Argomenti sulla riga di comando
ƒ
Java MyProgram -d file.txt
ƒ
java Crypt input.txt encrypt.txt
ƒ
java Crypt –d –k11 encrypt.txt output.txt
Linguaggi di Programmazione II
2003-04
87
File Crypt.java
88
try
{
for (int i = 0; i < args.length; i++)
{
if (args[i].charAt(0) == '-')
{
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;
// è 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));
if (args.length < 2 || args.length > 4) usage();
}
Linguaggi di Programmazione II
2003-04
89
Linguaggi di Programmazione II
2003-04
90
15
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();
}
catch (IOException exception)
{
System.out.println("Error processing file: "
+ exception);
}
}
/**
Stampa un messaggio che descrive l’uso corretto,
poi termina il programma.
}
if (decrypt) key = -key;
Encryptor crypt = new Encryptor(key);
crypt.encryptFile(inFile, outFile);
*/
public static void usage()
{
System.out.println(
"Usage: java Crypt [–d] [–kn] infile outfile");
}
catch (NumberFormatException exception)
{
System.out.println("Key must be an integer: "
+ exception);
}
Linguaggi di Programmazione II
2003-04
System.exit(1);
}
public static final int DEFAULT_KEY = 3;
}
Linguaggi di Programmazione II
2003-04
91
Scrittura di Oggetti su file
ƒ
Lettura di Oggetti da file
Per scrivere un oggetto su file
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
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
Esistono classi che permettono di
ƒ
Si individua l’altezza
Si individua la larghezza
Si memorizzano I valori separatamente
Per leggere un oggetto Rectangle
ƒ
94
Lettura di Oggetti da file
Per salvare un oggetto Rectangle
ƒ
Si leggono le caratteristiche codificate
separatamente dal file
Si organizzano tali caratteristiche in un
oggetto
Linguaggi di Programmazione II
2003-04
93
Esempio
ƒ
Per leggere un oggetto da 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
92
95
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
16
Vantaggi
ƒ
Per scrivere un intero oggetto
ƒ
ƒ
ƒ
Serializzazione
ƒ
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
ƒ
Linguaggi di Programmazione II
2003-04
Per scrivere oggetti di una classe
MyClass che implementa
Serializable in un flusso di oggetti
„
Appartenere a una classe che implementa
l’interfaccia Serializable
ƒ Non ha metodi
Linguaggi di Programmazione II
2003-04
MyClass mc = new ……
ObjectOutputStream out = new
ObjectOutputStream(new
FileOutputStream(“mc.dat”));
out.writeObject(mc);
Linguaggi di Programmazione II
2003-04
99
Serializzazione
„
98
Serializzazione
L’oggetto da inserire nel flusso deve
essere serializzabile
ƒ
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
97
Serializzazione
ƒ
La memorizzazione di oggetti in un flusso
viene detta serializzazione
100
Serializzazione: readObject
ƒ
Per leggere oggetti di una classe
MyClass che implementa
Serializable da un flusso di oggetti
ƒ
ƒ
Legge un Object da file
Restituisce un riferimento a tale Object
L’output necessita di un cast
MyClass mc = (MyClass) in.readObject();
ObjectInputStream in = new
ObjectInputStream(new
FileInputStream(“mc.dat”));
MyClass mc =
(MyClass)in.readObject();
Linguaggi di Programmazione II
2003-04
ƒ
Può lanciare un’eccezione controllata di tipo
ClassCastException
ƒ
Da catturare o dichiarare in una clausola
throws
101
Linguaggi di Programmazione II
2003-04
102
17
Serializzazione
Serializzazione: esempio
La serializzazione non riguarda solo
oggetti semplici
Ogni oggetto è serializzabile se
ottenuto da una classe che
implementa Serializable
ƒ
ƒ
„
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
‰
„
„
Linguaggi di Programmazione II
2003-04
Generano oggetti serializzabili
Implementano l’interfaccia Serializable
Linguaggi di Programmazione II
2003-04
103
104
File PurseTest.java
Public class PurseTest
{
public static void main(String[] args)
throws IOException,
ClassNotFoundException
{
Purse MyPurse;
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
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
105
else myPurse = new Purse();
106
private static final double NICKEL_VALUE = 0.05;
private static final double DIME_VALUE = 0.1;
private static final double QUARTE_VALUE = 0.25;
//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
Linguaggi di Programmazione II
2003-04
108
18
Accesso sequenziale e casuale
Accesso sequenziale
ƒ Accesso sequenziale
ƒ Ogni file su disco ha un puntatore
del file posto alla fine del file
ƒ Un file viene elaborato un byte alla
volta
ƒ Qualsiasi dato viene aggiunto alla
fine del file
ƒ Se il puntatore viene spostato i dati
sono sovrascritti
ƒ Accesso casuale
ƒ Possiamo accedere a posizioni
arbitrarie nel file
Linguaggi di Programmazione II
2003-04
109
Accesso casuale
110
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
Linguaggi di Programmazione II
2003-04
111
ƒ 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
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
19