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