Obiettivi del capitolo Capitolo 11 Gestione File ed Eccezioni 1 Lettura e scrittura file ASCII | File testo e binari | Fondamenti di Informatica Fondamenti di Informatica Lettura di file testo | | | Scrivere file testo Uso della classe Scanner Per leggere un file da disco, costruire un oggetto FileReader Poi con l’oggetto FileReader costruire un oggetto Scanner | Se il file esiste viene “svuotato” e vengono scritti i nuovi dati | Se il file non esiste ne viene creato uno nuovo vuoto | Metodi utilizzabili della classe Scanner per leggere dati da un file z next, z nextLine, z nextInt, e z nextDouble Fondamenti di Informatica Costruire un oggetto PrintWriter PrintWriter out = new PrintWriter("output.txt"); FileReader reader = new FileReader("input.txt"); Scanner in = new Scanner(reader); | 2 3 Fondamenti di Informatica 4 Scrivere file testo | Esempio Metodi per scrivere in un oggetto PrintWriter: z Leggere tutte le righe di in file e copiarle in un secondo file, precedute dal numero di riga | Esempio input file: | print, println out.println(29.95); out.println(new Rectangle(5, 10, 15, 25)); out.println("Hello, World!"); | Il file deve essere chiuso al termine della scrittura Mary had a little lamb Whose fleece was white as snow. And everywhere that Mary went, The lamb was sure to go! out.close(); | Altrimenti c’è il rischio di perdere dati Fondamenti di Informatica 5 Fondamenti di Informatica LineNumberer.java Esempio | | 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: File di output prodotto: /* /* /* /* 1 2 3 4 */ */ */ */ Mary had a little lamb Whose fleece was white as snow. And everywhere that Mary went, The lamb was sure to go! Il programma può essere utilizzato per numerare le righe di un file sorgente Java Fondamenti di Informatica 6 7 import import import import java.io.FileReader; java.io.IOException; java.io.PrintWriter; java.util.Scanner; public class LineNumberer { public static void main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("Input file: "); String inputFileName = console.next(); System.out.print("Output file: "); String outputFileName = console.next(); try { Fondamenti di Informatica 8 LineNumberer.java 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: LineNumberer.java FileReader reader = new FileReader(inputFileName); Scanner in = new Scanner(reader); PrintWriter out = new PrintWriter(outputFileName); int lineNumber = 1; while (in.hasNextLine()) { String line = in.nextLine(); out.println("/* " + lineNumber + " */ " + line); lineNumber++; } 34: 35: 36: 37: } System.out.println("Error processing file:" + exception); } } out.close(); } catch (IOException exception) { 9 Fondamenti di Informatica Fondamenti di Informatica Verifica Risposte 1. Cosa succede se si passa lo stesso nome di file di input e output al programma LineNumberer? 2. Cosa succede se viene fornito il nome di un file di input inesistente a LineNumberer? Fondamenti di Informatica 10 1. 2. 11 Quando l’oggetto PrintWriter viene creato, il file di output è svuotato. Quindi, avendo lo stesso nome, viene svuotato il file di ingresso. Il ciclo while non viene neppure eseguito. Il programma cattura l’eccezione FileNotFoundException, stampa il messaggio di erroe e termina. Fondamenti di Informatica 12 File Dialog Boxes File Dialog Boxes JFileChooser chooser = new JFileChooser(); FileReader in = null; if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { File selectedFile = chooser.getSelectedFile(); reader = new FileReader(selectedFile); . . . } Fondamenti di Informatica 13 Fondamenti di Informatica Formati testo e binario | 14 Text Format | I dati vengono memorizzati in due modi: | Text z Binary z Formato “leggibile” Sequenza di caratteri z | | Il numero 12,345 memorizzato come sequenza di caratteri'1' '2' '3' '4' '5' Si utilizzano i metodi delle classi Reader e Writer per elaborare input e output Lettura: FileReader reader = new FileReader("input.txt"); | Scrittura FileWriter writer = new FileWriter("output.txt"); Fondamenti di Informatica 15 Fondamenti di Informatica 16 Binary Format Binary Format | Dati sono rappresentati da bytes | Il numero 12,345 memorizzato come una sequenza di 4 bytes 0 0 48 57 | | | Lettura: FileInputStream inputStream = new FileInputStream("input.bin"); | Si utilizzano i metodi delle classi InputStream and OutputStream Scrittura: FileOutputStream outputStream = new FileOutputStream("output.bin"); Permette una gestione più compatta e d efficiente 17 Fondamenti di Informatica Fondamenti di Informatica Lettura di un singolo carattere da un file Text Format | Lettura di un singolo carattere da un file Binary Format Metodo read della classe Reader restituisce: z z | il successivo carattere come un intero [int] o l’intero -1 come fine file [EOF] Il successivo byte come un intero [int] z l’intero -1 alla fine del file Nota -1 è l’interpretazione in complemento a due di un insieme di bit tutti posti ad 1 Fondamenti di Informatica Method read della classe InputStream per leggere un singolo byte restituisce: z Reader reader = . . .; int next = reader.read(); char c; if (next != -1) c = (char) next; | 18 19 InputStream in = . . .; int next = in.read(); byte b; if (next != -1) b = (byte) next; Fondamenti di Informatica 20 Formati Text e Binary Formati Text e Binary Metodo write per scrivere un singolo byte o carattere | read e write sono gli unici metodi di lettura e scrittura forniti dalle classi di input e output dei file | Java stream package:ogni classe ha una responsabilità ben circoscritta | Fondamenti di Informatica 21 Compito della classe FileInputStream: interagire con file ed estrarre byte | Per leggere numeri, stringhe, o altri oggetti, si combina questa classe con altre | Fondamenti di Informatica Verifica 3. 4. Risposte Dovete leggere un file immagine che contiene il valori di colore di ciascun pixel. Utilizzate Reader o InputStream? Perché i metodi delle classi Reader e InputStream restituiscono un int e non un char o byte? Fondamenti di Informatica 22 23 3. L’immagine è memorizzato in formato binario, provate ad editare un file immagien con un editor di testi. Quindi si usa InputStream. 4. EOF viene individuato da -1. Se fosse restituito char o byte, non sarebbe stato possibile definire un carattere speciale diverso da un valore lecito. Fondamenti di Informatica 24 Obiettivi del Capitolo Gestione degli Errori Imparare a gettare le eccezioni | Essere in grado di progettare una tua classe di eccezioni | Capire la differenza tra eccezioni controllate e eccezioni non controllate | Imparare come catturare le eccezioni | Sapere quando e come catturare una eccezione | Fondamenti di Informatica 25 | | Approccio tradizionale: Il Metodo ritorna un codice d’errore Problema: Dimenticare di verificare la presenza di un messaggio d’errore z | z z 26 Lanciare Eccezioni Invece di programmare per successi | Eccezioni: Non possono essere trascurate z Manda direttamente a una gestione delle eccezioni del metodo fallito z x.doSomething() z Anche il programma deve fallire e lasciare il suo esecutore preoccupato Molte chiamate dei metodi dovrebbero essere verificate Fondamenti di Informatica Gestione degli Errori | La mancata notifica può passare inosservata Problema: La chiamata del metodo può non essere in grado di dire nulla circa il fallimento Dovresti sempre programmare per fallimenti: Lancia un oggetto eccezione per segnalare una condizione eccezionale illegal parameter value | Esempio: IllegalArgumentException exception = new IllegalArgumentException("Amount exceeds balance"); IllegalArgumentException: | if (!x.doSomething()) return false; throw exception; Fondamenti di Informatica 27 Fondamenti di Informatica 28 Lanciare Eccezioni | Esempio Non è necessario memorizzare l’oggetto eccezione in una variabile: throw new IllegalArgumentException("Amount exceeds balance"); | Quando viene lanciata una eccezione il metodo termina immediatamente z L’esecuzione continua con un gestore di eccezioni Fondamenti di Informatica 29 Gerarchia delle Classi di Eccezioni public class BankAccount { public void withdraw(double amount) { if (amount > balance) { IllegalArgumentException exception = new IllegalArgumentException("Amount exceeds balance"); throw exception; } balance = balance - amount; } . . . } Fondamenti di Informatica 30 Sintassi 11.1: Lanciare una Eccezione throw exceptionObject; Example: throw new IllegalArgumentException(); Purpose: To throw an exception and transfer control to a handler for this exception type Fondamenti di Informatica 31 Fondamenti di Informatica 32 Verifica Risposte Come si può modificare il metodo deposit per essere certi che il saldo non diventi mai negativo? Supponi di aver costruito un nuovo oggetto Bank Account con saldo zero e poi chiamare il metodo withdraw(10). Qual’è il valore di balance alla fine? 1. 2. Fondamenti di Informatica 33 1. 2. Lancia una eccezione se la somma che viene depositata è minore di zero. Il saldo è ancora zero perchè l’ultima istruzione del metodo withdraw non è mai stata eseguita. Fondamenti di Informatica Eccezioni Controllate e Non Controllate | Due tipi di eccezioni: z Due tipi di Eccezioni: z • Il compilatore controlla che non vengano ignorate • Dipendono da circostanze esterne che il programmatore non può impedire • La maggior parte avvegono quando si lavora con input e output • Per esempio, IOException Fondamenti di Informatica Eccezioni Controllate e Non Controllate | Controllate 35 34 Non Controllate: • Estendono la classe RuntimeException or Error • Sono colpa del programmatore • Esempi di eccezioni di Runtime: NumberFormatException IllegalArgumentException NullPointerException • Esempio di errore: OutOfMemoryError Fondamenti di Informatica 36 Eccezioni Controllate e Non Controllate | Le Categorie non sono perfette: z Eccezioni Controllate e Non Controllate | Scanner.nextInt Lancia la non controllata InputMismatchException String filename = . . .; FileReader reader = new FileReader(filename); Scanner in = new Scanner(reader); Il Programmatore non può impedire all’utente di inserire dati errati z Questa scelta rende la classe facile da usare per programmatori inesperti z | Ma, il costruttore FileReader può lanciare una FileNotFoundException Si incontrano eccezioni controllate quandi si programma con file e flussi Fondamenti di Informatica 37 Fondamenti di Informatica Eccezioni Controllate e Non Controllate | Per esempio, usa uno Scanner per leggere un file 38 Eccezioni Controllate e Non Controllate Due scelte: • Per eccezioni multiple: Gestire l’eccezione z Dire al compilatore che si vuole che il metodo termini quando occorre un’eccezione z public void read(String filename) throws IOException, ClassNotFoundException • Tieni in mente l’eredità gerarchica: Se il metodo può lanciare IOException e FileNotFoundException, usa solo IOException • Usa lo specificatore throws così il metodo può lanciare una eccezione controllata public void read(String filename) throws FileNotFoundException { FileReader reader = new FileReader(filename); Scanner in = new Scanner(reader); . . . } Fondamenti di Informatica 39 | Meglio dichiarare le eccezioni che gestirle incompetentemente Fondamenti di Informatica 40 Sintassi 11.2: Specificare Eccezioni Verifica accessSpecifier returnType methodName(parameterType parameterName, . . .) throws ExceptionClass, ExceptionClass, . . . 3. Supponi che il metodo chiami il costruttore FileReader e il metodo read della classe FileReader ,il quale può lanciare una IOException. Quale specificazione throws bisogna usare? 4. Perchè l’eccezione NullPointerException non è controllata? Example: public void read(BufferedReader in) throws IOException Purpose: To indicate the checked exceptions that this method can throw Fondamenti di Informatica 41 Fondamenti di Informatica Risposte 3. La specificazione lancia IOException è sufficente perchè FileNotFoundException è una sottoclasse di IOException. 4. Perchè i programmatori devono semplicemente controllare i puntatori null invece di tentare a gestire una NullPointerException. Fondamenti di Informatica 42 Catturare Eccezioni Si installa un gestore di eccezioni con l’enunciato try/catch | Il blocco try contiene l’enunciato che potrebbe causare una eccezione | La clausola catch contiene il gestore per un tipo di eccezioni | 43 Fondamenti di Informatica 44 Catturare Eccezioni | Catturare Eccezioni Esempio: L’enunciato nel blocco try viene eseguito | Se non occorre nessuna eccezione, la clausola catch viene saltata | Try { String filename = . . .; FileReader reader = new FileReader(filename); Scanner in = new Scanner(reader); String input = in.next(); int value = Integer.parseInt(input); . . . } catch (IOException exception) { exception.printStackTrace(); } catch (NumberFormatException exception) { System.out.println("Input was not a number"); } Fondamenti di Informatica 45 | Se occorre l’eccezione del tipo corrispondente, l’esecuzione salta alla clausola catch | Se occorre un altro tipo di eccezione, viene lanciata finchè non viene catturata da un altro blocco try Fondamenti di Informatica Sintassi 11.3: Blocco Try Generale Catturare Eccezioni | try { catch (IOException exception) block exception contiene il riferimento all‘oggetto eccezione che viene lanciato z catch può analizzare l’oggetto per cercare maggiori dettagli z exception.printStackTrace(): tabula la catena di chiamate di metodo che portano all’eccezione z Fondamenti di Informatica 46 47 statement statement . . . } catch (ExceptionClass exceptionObject) { statement statement . . . } catch (ExceptionClass exceptionObject) { statement statement . . . } . . . Fondamenti di Informatica 48 Sintassi 15.3: Blocco Try Generale Verifica Example: try { System.out.println("How old are you?"); int age = in.nextInt(); System.out.println("Next year, you'll be " + (age + 1)); } catch (InputMismatchException exception) { exception.printStackTrace(); } Purpose: To execute one or more statements that may generate exceptions. If an exception occurs and it matches one of the catch clauses, execute the first one that matches. If no exception occurs, or an exception is thrown that doesn't match any catch clause, then skip the catch clauses. Fondamenti di Informatica 49 5. 6. Fondamenti di Informatica Risposte 5. 50 Risposte Il costruttore FileReader agisce con successo e l’oggetto viene costruito. Successivamente l’invocazione in.next() lancia una NoSuchElementException, e il blocco try viene interrotto. Nessuna delle clausole catch corrisponde, così nessuna viene eseguita.Se nessuno dei metodi presenti nella catena di invocazione il programma termina. Fondamenti di Informatica Supponi che il file con il nome indicato esista ma sia vuoto. Traccia il flusso di esecuzione del blocco try di questo paragrafo. C’è differenza tra catturare eccezioni controllate e catturare eccezioni non controllate? 51 6. No,entrambi I tipi di eccezioni si catturano allo stesso modo, come puoi vedere nel codice esempio a pagina 558. Ricorda che IOException è una eccezione controllata e NumberFormatException è una eccezione non controllata. Fondamenti di Informatica 52 La Clausola finally La Clausola finally Deve eseguire reader.close() anche se occorre l’eccezione | Usa la clausola finally per codice che deve essere eseguito "no matter what" L’eccezione termina il metodo corrente | Pericolo: Può saltare codice essenziale | Esempio: | | reader = new FileReader(filename); Scanner in = new Scanner(reader); readData(in); reader.close(); // May never get here Fondamenti di Informatica 53 Fondamenti di Informatica Sintassi 15.4: La clausola finally La clausola finally | | Eseguita quando il blocco try è portato a termine in uno dei 3 modi seguenti: z Dopo l’ultimo enunciato del blocco try z Dopo l’ultimo enunciato della clausola catch, se il blocco try lancia una eccezione z Quando nel blocco try è lanciata una eccezione che non viene catturata Raccomandazione: non mischiare le clausole catch e finally nello stesso blocco try Fondamenti di Informatica 54 55 try { statement statement . . . } finally { statement statement . . . } Fondamenti di Informatica 56 Sintassi 15.4: La clausola finally Verifica Example: FileReader reader = new FileReader(filename); try { readData(reader); } finally { reader.close(); } 7. Perchè la variabile reader era dichiarata fuori dal blocco try? 8. Supponi che il file con il nome dato non esista. Traccia il flusso di esecuzione del segmento di codice in questa sezione. Proposta: Per assicurare che gli enunciati della clausola finally siano eseguiti o meno, l’enunciato nel blocco try lancia una eccezione Fondamenti di Informatica 57 Fondamenti di Informatica Progettare i vostri tipi di eccezione Risposte 7. 8. Se fosse stata dichiarata all’interno del blocco try, il suo scopo sarebbe stato esteso alla fine del blocco try, e la clausola catch non potrebbe essere chiusa. Il costruttore FileReader lancia una eccezione. La clausola finally è eseguita. Finchè reader è null, la chiamata a close non è eseguita. Poi, una clausola catch che sostituisce FileNotFoundException è localizzata. Se non esiste, il programma 59 termina. Fondamenti di Informatica 58 | Puoi progettare il tuo tipo di eccezione come sottoclassi di Exception o RuntimeException | if (amount > balance) { throw new InsufficientFundsException( "withdrawal of " + amount + " exceeds balance of “ + balance); } Fondamenti di Informatica 60 Progettare i vostri tipi di eccezione | | | Progettare i vostri tipi di eccezione Fare una eccezione non controllata – il programmatore potrebbe vietarla prima della chiamata di getBalance Estendi RuntimeException o una delle sue sottoclassi Fornire due costruttori 1. 2. public class InsufficientFundsException extends RuntimeException { public InsufficientFundsException() {} public InsufficientFundsException(String message) { super(message); } } Costruttore di Default Un costruttore che accetti una stringa che descriva la ragione dell’eccezione Fondamenti di Informatica 61 Fondamenti di Informatica Verifica Risposte 9. Qual’è la proposta della chiamata super(message) nel secondo costruttore InsufficientFundsException? 10. Supponi di leggere I dati di bank account da un file. Contrariamente alle aspettative, il prossimo valore inserito non è un double. Decidi di implementare un BadDataException. Quale classe di eccezione dovresti estendere? Fondamenti di Informatica 62 63 9. 10. Passare il messaggio di eccezione della stringa alla superclasse RuntimeException. Exception e IOException sono entrame buone scelte, perchè l’errore è oltre il controllo del programmatore, potrebbe essere una eccezione riscontrabile, così sarebbe errato estendere RuntimeException. Fondamenti di Informatica 64 Un programma completo | Un programma completo Programma z Chiedere all’utente il nome del file z Ci si aspetta che il file contenga dei valori z La prima riga del file contiene tutti numeri di valori z Le righe rimanenti contengono i dati z Tipici file di input: 3 1.45 -2.1 Fondamenti di Informatica 0.05 65 | Cosa potremmo sbagliare? z Il file potrebbe non esistere z Il file potrebbe avere dati in formato sbagliato z Chi può trovare gli errori? z Il costruttore FileReader può lanciare un’eccezione quando il file non esiste z I metodi che elaborano l’input necessitano di lanciare eccezioni se trovano errori nei dati del formato Fondamenti di Informatica Un programma completo | Un programma completo Quale eccezione può essere lanciata? | FileNotFoundException può essere lanciara dal costruttore FileReader z IOException può essere lanciata dal metodo close del FileReader z BadDataException, una classe di eccezione abitualmente controllata z Fondamenti di Informatica 66 Chi rimedia al difetto che l’eccezione riporta? z Solo il metodo main del programma DataSetTester interagisce con l’utente • Cattura le eccezioni • Stampa appropriati messaggi di errore • Da all’utente un altro tentativo per inserire il valore corretto 67 Fondamenti di Informatica 68 File DataSetTester.java 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: import java.io.FileNotFoundException; import java.io.IOException; import java.util.Scanner; 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: public class DataSetTester { public static void main(String[] args) { Scanner in = new Scanner(System.in); DataSetReader reader = new DataSetReader(); boolean done = false; while (!done) { try { Fondamenti di Informatica File DataSetTester.java 69 System.out.println("Please enter the file name: "); String filename = in.next(); double[] data = reader.readFile(filename); double sum = 0; for (double d : data) sum = sum + d; System.out.println("The sum is " + sum); done = true; } catch (FileNotFoundException exception) { System.out.println("File not found."); } catch (BadDataException exception) { System.out.println ("Bad data: " + exception.getMessage()); Fondamenti di Informatica Il metodo readFile della classe DataSetReader File DataSetTester.java 33: 34: 35: 36: 37: 38: 39: 40: } } catch (IOException exception) { exception.printStackTrace(); } | Costruisce l’oggetto Scanner Chiama il metodo readData | Completamente indifferente ad ogni eccezione | } } Fondamenti di Informatica 70 71 Fondamenti di Informatica 72 Il metodo readFile della classe DataSetReader Il metodo readFile della classe DataSetReader | Se c’è un problema con un input file, semplicemente passa l’eccezione al chiamante. finally { reader.close(); } return data; public double[] readFile(String filename) throws IOException, BadDataException // FileNotFoundException is an IOException { FileReader reader = new FileReader(filename); try { Scanner in = new Scanner(reader); readData(in); } Fondamenti di Informatica } 73 Fondamenti di Informatica Il metodo readFile della classe DataSetReader 74 Il metodo readFile della classe DataSetReader Legge il numero dei valori | Costruisce un array | Chiama readValue per ogni valore | | Controllo per due potenziali errori 1. 2. private void readData(Scanner in) throws BadDataException { if (!in.hasNextInt()) throw new BadDataException("Length expected"); int numberOfValues = in.nextInt(); data = new double[numberOfValues]; 3. Il File potrebbe non partire con un integer Il File potrebbe avere un dato in più dopo aver letto tutti i valori Non fare alcun tentativo per catturare le eccezioni for (int i = 0; i < numberOfValues; i++) readValue(in, i); if (in.hasNext()) throw new BadDataException("End of file expected"); Fondamenti di Informatica } 75 Fondamenti di Informatica 76 Il metodo readFile della classe DataSetReader Scenario 1. private void readValue(Scanner in, int i) throws BadDataException { 2. if (!in.hasNextDouble()) throw new BadDataException("Data value expected"); data[i] = in.nextDouble(); 3. } 4. 5. Fondamenti di Informatica 77 Fondamenti di Informatica 7. 8. readData non ha modificatori per l’eccezione e termina readFile non ha modificatori per l’eccezione e termina dopo l’esecuzione della clausola finally DataSetTester.main ha il modificatore per BadDataException; il modificatore stampa un messaggio, all’utente viene data un’altra opportunità per inserire il nome del file Fondamenti di Informatica 78 DataSetReader.java Scenario 6. DataSetTester.main chiama DataSetReader.readFile readFile chiama readData readData chiama readValue readValue non trova il valore atteso e lancia BadDataException readValue non ha modificatori per l’eccezione e termina 79 01: 02: 03: 04: 05: 06: import java.io.FileReader; import java.io.IOException; import java.util.Scanner; /** Reads a data set from a file. The file must have // the format numberOfValues value1 value2 . . . 07: 08: 09: 10: 11: */ 12: public class DataSetReader 13: { Fondamenti di Informatica 80 DataSetReader.java 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: DataSetReader.java /** Reads a data set. @param filename the name of the file holding the data @return the data in the file */ public double[] readFile(String filename) throws IOException, BadDataException { FileReader reader = new FileReader(filename); try { Scanner in = new Scanner(reader); readData(in); } finally { reader.close(); } Fondamenti di Informatica 81 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: return data; } /** Reads all data. @param in the scanner that scans the data */ private void readData(Scanner in) throws BadDataException { if (!in.hasNextInt()) throw new BadDataException("Length expected"); int numberOfValues = in.nextInt(); data = new double[numberOfValues]; for (int i = 0; i < numberOfValues; i++) readValue(in, i); Fondamenti di Informatica DataSetReader.java 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 82 DataSetReader.java if (in.hasNext()) throw new BadDataException("End of file expected"); } /** 60: 61: 62: 63: 64: 65: 66: } if (!in.hasNextDouble()) throw new BadDataException("Data value expected"); data[i] = in.nextDouble(); } private double[] data; Reads one data value. @param in the scanner that scans the data @param i the position of the value to read */ private void readValue(Scanner in, int i) throws BadDataException { Fondamenti di Informatica 83 Fondamenti di Informatica 84 Verifica 11. 12. Risposte Perchè il metodo DataSetReader.readFile non trova nessuna eccezione? Supponi che l’utente abbia specificato un file esistente ma vuoto. Descrivi il flusso di esecuzione. Fondamenti di Informatica 85 Risposte 12. DataSetTester.main chiama DataSetReader.readFile, che chiama readData. La chiamata in.hasNextInt() ritornafalse, e readData lancia una BadDataException. Il metodo readFile non lo trova, così torna al main, dove è catturato. Fondamenti di Informatica 87 11. Non è in grado di fare nulla con loro. La classe DataSetReader è una classe riutilizzabile che potrebbe essere usata per sistemi con differenti linguaggi e differenti interfacce utente. Così non può esere innestata in un dialogo con il programma dell’utente. Fondamenti di Informatica 86