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