Lettura di matrici da file Come procedere?

4
StringTokenizer: esempio
import java.io.*;
import java.util.*;
Lettura di matrici da file
class prova
{
public static void main(String[] a)
{
String s="ciao a tutti";
StringTokenizer st=new StringTokenizer(s);
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
}
}
2
5
Come procedere?
Lettura matrice: esempio - I
import java.io.*;
import java.util.*;
Occorre leggere una riga per volta
Suddividere la riga in token (sottostringhe)
separate da delimitatori) e aggiungere le
sottostringhe alla matrice.
class p2
{
public static void main(String[] a) throws Exception
{
int[][] mat=new int[2][3];
String filename="prova.txt";
BufferedReader br=new BufferedReader(new InputStreamReader(new
FileInputStream(new File(filename))));
String line =br.readLine();
int x=0;
int y;
3
La classe StringTokenizer
Consente di suddividere una stringa in Tokens, separati da un
delimitatore
Utilizzo simile all’ Enumeration
Parte del package java.util
Costruttori:
– StringTokenizer(String str) crea uno StringTokenizer, utilizzando il
carattere spazio “ “ come separatore
– StringTokenizer(String str, String delim): crea uno StringTokenizer,
utilizzando la stringa delim come separatore
Metodi di accesso ai tokens:
– boolean hasMoreTokens() controlla se ci sono ancora token da leggere
– String nextToken() restituisce il token successivo
6
Lettura matrice: esempio - II
while(line !=null)
{
y=0;
StringTokenizer st=new StringTokenizer(line,";");
while(st.hasMoreTokens())
{
mat[x][y]=Integer.parseInt(st.nextToken());
y++;
}
x++;
line=br.readLine();
}
7
Lettura matrice: esempio - III
10
Rispondere all’imprevisto
for(x=0;x<2;x++)
{
for(y=0;y<3;y++)
System.out.print(mat[x][y]+" ");
System.out.println();
}
Consideriamo il caso in cui l’argomento del
metodo parseInt è “pippo”
Il metodo parseInt non può correggere l’errore
Non può far sapere all’utente che c’è stato un
errore
}
}
– Il metodo restituisce un int …
Questo non è compito di parseInt
11
Exception
Un modo alternativo di terminazione dei metodi basato
sull’uso dell’istruzione throw
Eccezioni
throw riferimento
– dove riferimento è un oggetto di una sottoclasse della classe
Exception, solitamente:
throw new Exception-Class(Argomento String)
– dove Exception-Class è una sottoclasse di Exception
Quando il metodo esegue l’istruzione throw, si dice che
lancia (throw) un’eccezione.
9
Previsione dell’imprevisto
Immaginiamo il seguente codice
int numberInStock = Integer.parseInt(br.readLine());
Cosa succede se:
– L’oggetto BufferedReader rappresenta un file su floppy disk
che l’utente ha erroneamente estratto ?
– L’oggetto BufferedReader rappresenta una connessione alla
rete che è fallita a causa di un guasto ?
– L’operatore immette una sequenza di cifre troppo lunga ?
– L’operatore non immette una sequenza di cifre ?
12
Lanciare un’eccezione
Consideriamo la catena di chiamate
main Æ method1 Æ method2
– Supponiamo che method2 incontra un imprevisto e lancia
l’eccezione throw riferimento ad oggetto Exception
– Il metodo in esecuzione termina immediatamente, l’Exception
passa attraverso ogni invocazione della catena, forzando
ogni metodo a terminare. Viene visualizzato:
Some Exception
at TryThrow.method2(TryThrow.java:18)
at TryThrow.method1(TryThrow.java:15)
at TryThrow.main(TryThrow.java:12)
13
Esempio
16
Etichettatura delle eccezioni
Il costruttore di una Exception prende come
argomento una String che viene stampata
quando si visualizza la catena delle invocazioni
Il metodo parseInt contiene un’istruzione simile a
throw new NumberFormatException(Argomento String)
Questa istruzione crea un nuovo ogetto
NumberFormatException e lancia il riferimento a
questo oggetto.
NumberFormatException è una sottoclasse di
Exception
throw new FileNotFoundException(“log file is” +
“always necessary”);
14
La clausola throws
17
Trattare l’imprevisto
Come evitare la terminazione di un programma in caso
di eccezione ?
Il verbo throw non è del tutto sconosciuto …
– Spesso Java richiede che si includa la clausola throws
nell’intestazione della dichiarazione di un metodo:
– Java fornisce ai metodi un modo per catturare (catch)
qualsiasi Exception lanciata sul loro percorso dai metodi che
invocano
– Catturando l’Exception si interrompe la catena che porta alla
terminazione del programma
– viene recuperato il controllo e si può trattare la situazione in
modo meno drastico
public static void main(String[] a) throws Exception
– Qualsiasi metodo che potrebbe lanciare un’Exception deve
indicarlo nella sua dichiarazione con la clausola throws
– La clausola throws è composta dalla parola chiave e dalla
lista delle sottoclassi di Exception che possono essere
lanciate dal metodo
– Questo requisito si applica anche ai metodi che possono
lanciare l’Exception indirettamente invocando altri metodi
Per catturare una Exception, le istruzioni contenenti
invocazioni di metodi che lanciano Exception devono
essere tra parentesi e precedute dalla parola chiave try
15
La classe Exception
Il riferimento che appare nell’istruzione throw deve
riferirsi a un oggetto della classe Exception
– Ogni oggetto istanza di una sottoclasse di Exception è anche
un oggetto Exception
Perché esistono più classi Exception ?
– distinzioni tra i vari tipi di situazioni impreviste, es:
throws IOException
throws FileNotFoundException, RemoteException:
– IOException è una sottoclasse di Exception
– FileNotFoundException e RemoteException sono sottoclassi
di IOException
18
Try
try { // parte try
someObject.someMethod();
} catch (Exception e) { // parte catch
le istruzioni sono eseguite solo se
l’eccezione è lanciata all’interno di try
}
19
static Movie readMovie(BufferedReader br) throws IOException {
String name;
int playingTime;
boolean gotGoodData; // True if name and playingTime have valid data
Movie newMovie;
name = br.readLine();
gotGoodData = false;
while (!(name==null || gotGoodData)) {
gotGoodData = true;
// Optimistic!
try { playingTime = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) { // Skip this movie; do next one.
System.err.print("Bad playing time data for "+name);
System.err.println(" -- movie skipped");
gotGoodData = false;
name = br.readLine();
}
}
if (name==null) return null;
else return new Movie(name,playingTime);
}
22
Versione corretta
Esempio
static Movie readMovie(BufferedReader br) throws IOException {
String name;
int playingTime;
Movie newMovie;
name = br.readLine();
if(name == null)
return null;
playingTime = Integer.parseInt(br.readline());
newMovie = new Movie(name, playingTime);
return newMovie;
}
Come gestire un errore dei dati in ingresso inviando un messaggio all’utente ?
20
Esempio
rivisto
static Movie readMovie(BufferedReader br) throws IOException {
String name;
int playingTime;
Movie newMovie;
name = br.readLine();
if(name == null)
return null;
try {
playingTime = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) { // Skip this movie; do next one
System.err.print("Bad playing time data for "+name);
throw e;
}
newMovie = new Movie(name, playingTime);
return newMovie;
}
21
static Movie readMovie(BufferedReader br) throws IOException {
String name;
int playingTime;
Movie newMovie;
name = br.readLine();
if(name == null) return null;
try { playingTime = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) { // Skip this movie; do next one
System.err.print("Bad playing time data for "+name);
System.err.println(" -- movie skipped");
name = br.readLine();
if(name == null) return null;
playingTime = Integer.parseInt(br.readLine());
newMovie = new Movie(name, playingTime);
return newMovie;
}
// questo codice è eseguito se parseInt non lancia una NumberFormatException
newMovie = new Movie(name, playingTime);
return newMovie;
} // dove è il problema ?
Rimediare
ad un errore
23
Responsabilità per l’imprevisto
Ogni oggetto si assume la responsabilità del suo
comportamento (comprese le circostanze impreviste)
– Ad esempio consideriamo gli oggettI:
• NetHeadlineScanner modella un servizio di titoli in rete. Il suo compito
è visualizzare i titoli che contengono alcune parole chiave. I titoli sono
ottenuti dall’oggetto NetHeadlines
• NetHeadlines ottiene in continuazione i titoli delle notizie da una
qualsiasi delle varie sorgenti alternative ed è implementato usando il
NetReader
• L’oggetto NetReader legge in continuazione le ultime informazioni da
una sorgente della rete. A sua volta, il NetReader può essere
implementato usando il BufferedReader
• L’oggetto BufferedReader è costruito dall’InputStream consegnato
dall’oggetto Socket connesso. Socket è la classe predefinita di java
che modella le connessioni di basso livello alla rete
24
Responsabilità per l’imprevisto (2)
L’oggetto NetHeadlineScanner invoca il metodo
readLine della classe NetHeadlines che a sua
volta invoca il metodo readLine della classe
NetReader, che a sua volta invoca il metodo
readLine della classe BufferedReader
In questo caso l’imprevisto è la non disponibilità
improvvisa della sorgente corrente di notizie
– Quali classi dovrebbero assumersi la responsabilità
dell’inconveniente ?
– Quale comportamento dovrebbero seguire ?
25
Responsabilità per l’imprevisto (3)
Si può risalire al punto in cui è stata generata
l’Exception ed esaminare gli oggetti sulla catena di
invocazioni cercando di individuare quale oggetto
sia in grado di agire rispetto all’eccezione
28
CheckURL: prima versione
import java.net.*;
import java.io.*;
class CheckURL {
public static void main(String[] a) throws Exception {
URL u = new URL(a[0]);
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
int responseCode = uc.getResponseCode();
System.out.println(responseCode);
if (responseCode >= 300)
System.out.println("bad");
else
System.out.println("good");
}
Nel caso in cui non è possibile stabilire una connessione perché il server web non
esiste il programma dovrebbe rispondere bad, ma …
– BufferedReader.readLine lancia l’Exception
• Non sarà lui a catturarla
• Non è riuscito a trattare la non disponibilità della sorgente di
rete perché il BufferedReader è una sorgente di dati
idealizzata e non sa se i dati che sta fornendo provengano
dalla rete, da un file o dalla tastiera
• Per questo lancia un’Exception
26
Responsabilità per l’imprevisto (4)
Come si comportano gli altri oggetti ?
– L’oggetto NetReader sa che sta leggendo dalla locazione di rete
della sua sorgente
• Ottenere i dati è il suo comportamento
• Se i dati non sono disponibili, lancia un’eccezione
– L’ogetto NetHeadlines conosce delle sorgenti di rete alternative
• Potrebbe rispondere catturando l’Exception, selezionando un indirizzo di
rete diverso creando un oggetto NetReader basato sulla nuova sorgente
di rete e continuando
– NetHeadlineScanner non deve fare niente …
• Potrebbe trattare l’Exception meglio di NetHeadlines, ma questo non
rientra nelle sue responsabilità (che riguardano solo la selezione dei titoli)
27
Le eccezioni non sono sempre errori
Scriviamo un programma che riceve un URL come argomento
dalla linea di comando e stampa “good” se la URL corrisponde
all’indirizzo di una pagina web, “bad” altrimenti
– Si possono usare i response codes restituiti dai web server
– I codici maggiori o uguali a 300 indicano un errore nella URL
• Ad esempio 404 significa che la pagina non esiste
• 403 significa che la risorsa non è accessibile
– La classe HttpURLConnection nella libreria java.net modella le
connessioni HTTP a risorse web specificate da URL
– Possiamo creare tale oggetto mandando un messaggio
openConnection ad un oggetto URL
– Avuto un oggetto HttpURLConnection, gli possiamo mandare un
messaggio getResponseCode
29
CheckURL:
versione corretta
import java.net.*;
import java.io.*;
class CheckURL {
public static void main(String[] a) throws Exception {
try {
URL u = new URL(a[0]);
HttpURLConnection uC = (HttpURLConnection) u.openConnection();
int responseCode = uc.getResponseCode();
System.out.println(responseCode);
if (responseCode >= 300)
System.out.println("bad");
else
System.out.println("good");
} catch (Exception e) {
System.out.println("bad");
}
}
}