4. Alcuni strumenti (I/O, eccezioni, package)

Transcript

4. Alcuni strumenti (I/O, eccezioni, package)
Programmazione
in Java
Quarta lezione
Cristian Del Fabbro
Di cosa si parla oggi?
●
Eclipse
●
Garbage Collector
●
I/O da tastiera e da file
●
Eccezioni
●
Alcune classi utili
●
Una classe per i numeri complessi
●
Esempio per casa
Eclipse
●
●
●
IDE (Integrated Development Environment)
–
scrivere
–
compilare
–
eseguire
È scritto principalmente in Java e pensato
per sviluppare programmi in Java
Disponibili svariati plugin (scritti in Java)
–
VisualJava
Perché Eclipse?
●
Autocompletamento
●
Help in linea durante la digitazione
●
●
●
●
Segnala gli errori di sintassi mentre si scrive
il codice
Suggerisce cosa fare per correggere gli
errori più comuni
Mostra la gerarchia dei pacchetti e delle
classi
Permette il debug
Garbage Collector
●
●
●
Quando un oggetto non ha riferimenti che
puntano ad esso il programma non lo può
più usare (garbage)
Generalmente bisogna ricordarsi di liberare
la memoria allocata e non più utilizzata
Java gestisce in automatico la deallocazione
della memoria non più utilizzata
–
il programmatore ha un problema in meno
I/O da tastiera
●
Serve per poter interagire con l'utente
●
L'INPUT permette di ricevere dei dati
–
●
System.in è un InputStream
L'OUTPUT permette di visualizzare dei dati
–
System.out è un OutputStream
EasyIn
●
●
È una semplice classe che permette di
ricevere l'input da tastiera senza curarsi dei
dettagli
Permette di leggere:
–
numeri interi – readInt() – readLong()
–
numeri reali – readFloat – readDouble()
–
stringhe – readString() – readChar()
–
valori booleani – readBoolean()
Salutare l'utente
public class Hello {
public static void main(String[] args){
EasyIn input = new EasyIn();
System.out.println("Ciao, come ti chiami?");
String nome = input.readString();
System.out.println("Ciao " + nome + "!");
}
}
I/O da file
●
I dati vengono presi e scritti su un file
●
Si parla di flusso (stream) di dati
●
●
Attraverso l'INPUT si prelevano i dati da un
file
Attraverso l'OUTPUT si scrivono i dati in un
file
Leggere un file
●
Quando si vuole prelevare i dati da un file
bisogna:
–
sapere il percorso del file
–
aprire uno stream di input
–
prelevare i dati
–
controllare se si è raggiunta la fine del file (EOF)
–
verificare se ci sono degli errori
–
chiudere il file
Classi per leggere
●
●
●
Ad un file bisogna associare uno stream di
input:
–
FileInputStream
–
FileReader
Possono leggere solo array di caratteri
Una classe più utile è BufferedReader che
permette di leggere una riga intera e
memorizzarla in una stringa
Leggere un file di testo
String name = “nomefile”;
FileReader f = new FileReader(name);
BufferedReader file = new BufferedReader(f);
while (file.ready()) {
String line = file.readLine();
System.out.println(line);
}
file.close();
Scrivere su un file
●
Quando si vuole scrivere dei dati su un file
bisogna:
–
sapere il percorso del file
–
aprire uno stream di output
–
scrivere i dati
–
verificare se ci sono degli errori
–
chiudere il file
Classi per scrivere
●
●
●
Ad un file bisogna associare uno stream di
output:
–
FileOutputStream
–
FileWriter
Possono scrivere solo array di caratteri
Una classe più utile è PrinterWriter che
permette di usare i metodi print e println
come con lo standard output
Numerare le righe di un file
FileReader r = new FileReader(inName);
BufferedReader fileInput = new BufferedReader(r);
FileWriter w = new FileWriter(outName);
PrinterWriter fileOutput = new PrinterWriter(w);
int count = 1;
while (fileInput.ready()) {
String line = fileInput.readLine();
fileOutput.println(count + ") " + line);
count++;
}
fileInput.close();
fileOutput.close(); // Ricordarsi di chiudere SEMPRE i file in scrittura!
Accesso casuale ai file (1)
●
●
I file trattati come stream possono essere
letti in una sola direzione: una volta letto un
byte si passa al successivo e non si può
tornare indietro
Per poter andare “avanti” e “indietro” in un
file bisogna usare la class
RandomAccessFile che permette di
spostarsi avanti e indietro all'interno del file
Accesso casuale ai file (2)
●
●
Un file ad accesso casuale si può aprire in
lettura, in scrittura o in entrambi i metodi:
–
new RandomAccessFile(“file.txt”,”r”)
–
new RandomAccessFile(“file.txt”,”w”)
–
new RandomAccessFile(“file.txt”,”rw”)
oltre ai metodi normalmente disponibili per
leggere e scrivere sono presenti:
–
void seek(long i) // serve per posizionarsi al byte i-esimo del file
–
long getFilePointer() // ritorna la posizione del prossimo byte da
leggere
Eccezioni (1)
●
●
●
Quando si lavora con dei file (o in generale
quando si interagisce con il “mondo” esterno
ad un programma) si possono generare delle
eccezioni ed errori.
Una eccezzione è un oggetto che definisce
una situazione inusuale o erronea.
Un errore è simile ad una eccezione ma in
generale non può essere corretta e non può
essere intercettato
Eccezioni (2)
●
●
●
I metodi delle classi possono generare
eccezioni
Quando si utilizza un metodo che può
generare un'eccezione bisogna “catturarla”
Per far questo bisogna utilizzare la struttura
“try/catch”:
try {
// chiamate a metodi che generano eccezioni
} catch (ExceptionType exception) {
// gestione dell'errore
}
Eccezioni: esempio
import java.io.*;
public class SimpleRead {
public static void main (String[] args) {
String name = “nomefile”;
try {
FileReader f = new FileReader(name); // genera eccezione “FileNotFound”
BufferedReader file = new BufferedReader(f);
while (file.ready()) {
String line = file.readLine(); // genera eccezione di “I/O”
System.out.println(line);
}
file.close();
} catch (FileNotFoundException e) {
System.out.println("Il file non è stato trovato!");
} catch (IOException e) {
System.out.println("Errore nella lettura del file.");
}
}
}
Eccezioni: metodo alternativo
●
●
●
Esiste un altro modo di trattare le eccezioni
ed è quello di non gestirle ma ti notificarle al
metodo chiamante
Si demanda la gestione ad un livello
superiore
Per far questo bisogna usare la sintassi:
–
public void read throws ExceptionType [, ExceptionType ] {
// corpo del metodo
}
Esempio Throws (1)
public class SimpleReadThrows {
BufferedReader file;
public SimpleReadThrows(String name) throws FileNotFoundException {
FileReader f = new FileReader(name);
file = new BufferedReader(f);
}
public void read() throws IOException {
while (file.ready()) {
String line = file.readLine();
System.out.println(line);
}
file.close();
}
// continua nella prossima slide
Esempio Throws (2)
// continua dalla precedente slide
public static void main(String[] args) throws IOException {
EasyIn input = new EasyIn();
System.out.println("Quale file vuoi visualizzare?");
String name = input.readString();
try {
SimpleReadThrows srt = new SimpleReadThrows(name);
srt.read();
} catch (FileNotFoundException e) {
System.out.println("File non trovato!");
}
}
}
Package
●
Per poter usare classi già pronte ci sono tre
modi:
–
invocare esplicitamente la classe:
java.util.Vector vector = new java.util.Vector();
–
importare la classe:
import java.util.Vector; // all'inizio del file
[...]
Vector vector = new Vector();
–
importare tutto il pacchetto:
import java.util.*; // all'inizio del file
[...]
Vector vector = new Vector();
StringTokenizer = new StringTokenizer();
Vector
●
●
java.util.Vector
–
permette di gestire array che cambiano
dimensione e tipo in modo dinamico
–
funziona solo per le classi, non per tipi primitivi
metodi:
–
void addElement(Object obj)
–
void insertElementAt(Object obj, int index)
–
removeElementAt(int index)
–
Object elementAt(int index)
–
boolean size()
Esempio di uso di Vector
Vector vector = new Vector();
vector.addElement(“Primo elemento”);
vector.addElement(“Ultimo elemento”);
vector.insertElementAt(“Secondo elemento”,1);
vector.insertElementAt(“Terzo elemento”,1);
vector.removeElementAt(1);
vector.insertElementAt(“Terzo elemento”,2);
for (int i=0; i < vector.size(); i++) {
System.out.println((String)vector.elementAt(i));
}
StringTokenizer
●
java.util.StringTokenizer
–
serve per processare una stringa composta da
più campi. Es.:
Mario|Rossi|impiegato|Udine
●
costruttore: StringTokenizer(String str)
●
metodi:
–
int countTokens()
–
boolean hasMoreTokens()
–
String nextToken()
Esempio di StringTokenizer
StringTokenizer st = new StringTokenizer("Questa è una prova");
int n = st.countTokens();
for (int i=0; i < n ; i++)
System.out.println(st.nextToken());
st = new StringTokenizer("Mario|Rossi|impiegato|Udine","|");
while (st.hasMoreElements())
System.out.println(st.nextToken());
Date
●
●
●
java.util.Date
–
sapere data e ora in cui viene eseguito lo script
–
semplici operazioni di confronto fra date
costruttori:
–
Date()
–
Date(long date)
metodi:
–
boolen after(Date arg)
boolean equals(Date arg)
boolean before(Date arg)
GregorianCalendar
●
java.util.GregorianCalendar
–
●
serve per “formattare” le date a seconda del
calendario locale della località
costruttori:
–
GregorianCalendar()
–
GregorianCalendar(int year, int month, int day)
–
GregorianCalendar(int year, int month, int day, int hour, int min)
–
GregorianCalendar(int year, int month, int day, int hour, int min, int sec)
Esempio di uso di Date
Date date = new GregorianCalendar(year,month,day).getTime();
GregorianCalendar now_gregorian = new GregorianCalendar();
int day_now = now_gregorian.get(Calendar.DATE);
int month_now = now_gregorian.get(Calendar.MONTH);
int year_now = now_gregorian.get(Calendar.YEAR);
Date now = new GregorianCalendar(year_now,month_now,day_now).getTime();
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println("Data attuale: " + df.format(now));
System.out.println("Data inserita: " + df.format(date));
if (date.equals(now)) {
System.out.println("Le due date sono identiche");
} else if (date.before(now)) {
System.out.println("La data inserita è precedente alla data attuale");
} else { // implicitamente vale date.after(now)
System.out.println("La data inserita è seguente alla data attuale");
}
Alcuni esempi di classi
●
●
●
●
Le classi sono costituite da uno o più
costruttori, dalle proprietà e dai metodi
i costruttori servono per inizializzare
l'oggetto
le variabili servono per caratterizzare un
oggetto
i metodi servono per l'interazione fra gli
oggetti
Il numero complesso (1)
●
●
●
Un numero complesso è caratterizzato da
una parte reale e una parte immaginaria
[proprietà => variabili]
Bisogna costruire un oggetto “numero
complesso” a partire dalla parte reale e
immaginaria [costruttore]
Dell'oggetto bisogna sapere la sua parte
reale e immaginaria, poter stamparlo in
formato “n+mi” e poter fare alcune
operazioni (come la somma) [metodi]
Il numero complesso (2)
●
Le proprietà (variabili) del numero complesso
sono:
–
float real;
–
float imm;
Il numero complesso (3)
●
Costruttori:
–
se non ci sono dati crea il numero 0+0i
Complex() {
real = 0;
imm = 0;
}
–
dati i numeri “n” e “m” crea il numero n+mi
Complex(float n, float m) {
real = n;
imm = m;
}
Il numero complesso (3)
●
●
ritorna la parte reale e immaginaria di un
numero:
–
public float getReal() {
return real;
}
–
public float getImm() {
return imm;
}
modulo del numero complesso
–
public float getModule() {
return (float)Math.sqrt(real*real + imm*imm);
}
●
somma di un numero complesso
–
●
public void addComplex(Complex value) {
real += value.getReal();
imm += value.getImm();
}
ritornare il complesso coniugato
–
public Complex getConiugate() {
return new Complex(real,-imm);
}
Il numero complesso (4)
●
Restituire un formato “stringa” del numero
complesso per poterlo stampare a video
–
public String toString() {
String s = new String();
s += (new Float(real)).toString();
if (imm >=0)
s += “+”;
s += (new Float(imm)).toString() ;
s += “i”;
return s;
}
Il numero complesso (5)
●
Esempio di utilizzo:
Complex a = new Complex();
// 0+0i
Complex b = new Complex(5,3); // 5+3i
Complex c = new Complex(-6,4); // -6+4i
a.addComplex(b); // somma 5+3i ad a
a.addComplex(c.getConiugate()); // somma -6-4i ad a
System.out.println("a vale: " + a.toString());
// a vale: -1.0-1.0i
System.out.println("La parte reale di a e': " + a.getReal());
// La parte reale di a e': -1.0
System.out.println("La parte immaginaria di a e': " + a.getImm());
// La parte immaginaria di a e': -1.0
System.out.println("Il modulo di a e': " + a.getModule());
// Il modulo di a e': 1.4142135
Esempio per casa (1)
●
●
Scrivere una classe per memorizzare i dati di
una persona:
–
nome
–
cognome
–
luogo di nascita
–
data di nascita
Aggiungere alla classe dei metodi che
ritornino il nome e il cognome, la data di
nascita in formato esteso e l'età
Esempio per casa (2)
●
Preparare un file con una serie di
informazioni per riga, ad es:
–
●
Mario|Rossi|impiegato|Udine|23/3/1952
Carlo|Bianchi|studente|S. Donà|2/12/1990
Franco|Franchi|comico|Frafroreano|4/4/1944
Scrivere un programma che legge il file e
scrive un altro file come nell'esempio della
prossima slide
Esempio per casa (3)
Mario Rossi di professione impiegato
Nato a Udine il 23 febbraio 1952
Quest'anno ha già compiuto 57 anni
Carlo Bianchi di professione studente
Nato a S. Donà il 12 dicembre 1990
Quest'anno deve compiere 15 anni
Franco Franchi di professione comico
Nato a Fraforeano il 4 aprile 1944
Quest'anno ha già compiuto 61 anni