Input / Output
Parte I
Corso di Linguaggi di
Programmazione ad Oggetti 1
A.A. 2003/04
A cura di
Gianmaria Mancosu
1
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 2
Console I/O
l
l
l
l
Molte applicazioni devono interagire con l’utente
attraverso del testo
L’utente inserisce del testo sulla tastiera (standard
input)
Il programma usa la finestra del terminale per
mostrare il proprio output (standard output)
Il programma visualizza i messaggi di errore su un
canale separato (standard error)
Input / Output
Gianmaria Mancosu
2
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 3
Console I/O
l
l
Analogamente al C++, Java definisce alcuni oggetti di
default che sono legati allo standard input, standard
output e standard error
System.out
l
l
System.in
l
l
È una istanza di PrintStream che si riferisce alla finestra del
terminale che ha lanciato l’applicazione
È una istanza di InputStream collegata con la tastiera
System.err
l
È una istanza di PrintStream che si riferisce alla finestra del
terminale che ha lanciato l’applicazione
Input / Output
Gianmaria Mancosu
3
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 4
Scrivere in System.out
l
println(arg)
l
l
print(arg)
l
l
Stampa l’argomento e un ritorno a capo (‘\n’)
Stampa l’argomento senza nessun ritorno a capo
Esempio:
static void main(String args[]) {
System.out.println(“Hello, World!”);
}
Input / Output
Gianmaria Mancosu
4
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 5
Scrivere in System.out
l
I metodi println e print sono “sovraccaricati” (overloading) per
ciascuno dei tipi primitivi e per Object e String. Per esempio:
void
void
void
void
void
void
void
void
void
l
println(boolean)
println(char)
println(int)
println(long)
println(double)
println(float)
println(char[])
println(java.lang.String)
println(java.lang.Object)
In particolare println(Object) richiama il metodo toString dell’oggetto
passato come argomento
Input / Output
Gianmaria Mancosu
5
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 6
Standard Input
l
Leggere l’input da console è un po’ più complicato…
1.
2.
3.
4.
l
l
l
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(ir);
String line = br.readLine();
System.out.println(“User types: “ + line);
Il problema è che System.in rappresenta un flusso di
byte e non di caratteri
La riga 1 si occupa della conversione tra byte e
caratteri (Unicode)
La riga 2 invece permette di utilizzare il metodo
readLine che legge lo standard input una linea alla
volta (riga 3)
Input / Output
Gianmaria Mancosu
6
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 7
Il package java.io
l
l
l
L’input/output è uno degli elementi più importanti della
programmazione
Java mette a disposizione un insieme molto fornito di
classi legate all’I/O
Nel package java.io troviamo le seguenti categorie di
classi:
l
l
l
l
l
Input / Output
Files
Pipes
Filtering
Exceptions
Input / Output
Gianmaria Mancosu
7
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 8
La classe File
l
l
l
l
È una rappresentazione astratta dei file e della
gerarchia delle directory (path) indipendente
dalla piattaforma
Contiene molti metodi per la gestione dei file e
per ottenere informazioni su di essi
Le directory sono considerate semplicemente
dei file (Unix-like)
Non permette l’accesso diretto al contenuto dei
file (occorre usare altre classi: es. FileReader,
FileWriter)
Input / Output
Gianmaria Mancosu
8
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 9
La classe File
l
La classe File mette a disposizione diversi
costruttori in overload:
l
Definizione di un file
File myFile = new File(“myfile.txt”);
l
Definizione di un file in una directory
File myFile = new File(“mydir”, “myfile.txt”);
l
Definizione di un file in una directory tramite un
oggetto File
File myDir = new File(“mydir”);
File myFile = new File(myDir, “myfile.txt”);
Input / Output
Gianmaria Mancosu
9
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 10
La classe File
l
Dopo aver creato un oggetto File è possibile usarlo
per avere delle informazioni sul file specificato:
l
String getName()
l
l
String getPath()
l
l
Restituisce la lunghezza del file
boolean canWrite()
l
l
Restituisce il path del file
long length()
l
l
Restituisce il nome del file
Restituisce true se è possibile scrivere nel file (es. non è readonly)
boolean isDirectory()
l
Restituisce true se l’oggetto file identifica una directory
Input / Output
Gianmaria Mancosu
10
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 11
La classe File
l
Alcuni metodi messi a disposizione da File per la gestione del file
system:
l
boolean exists()
l
boolean delete()
l
l
l
Crea la directory specificata dall’oggetto file
String[] list()
l
l
Cancella il file corrispondente
boolean mkdir()
l
l
Restituisce true se il file esiste
Restituisce la lista dei nomi di file presenti nella directory specificata
dall’oggetto
boolean renameTo()
l
Cambia il nome del file secondo quanto specificato dal parametro
Input / Output
Gianmaria Mancosu
11
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 12
File I/O
l
l
Ricordiamo che la classe File è una rappresentazione
astratta dei file e non permette l’accesso al contenuto
Per leggere o scrivere in un file si utilizzano altre
classi:
l
l
l
Input:
FileReader
Output: FileWriter
Esempio:
File myFile = new File(“myfile.txt”);
FileReader in = new FileReader(myFile);
char c = (char) in.read(); // coercion!!
Input / Output
Gianmaria Mancosu
12
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 13
File: un esempio
1
2
3
4
5
6
7
8
9
10
11
12
13
File myFile = new File(“myfile.txt”);
try {
FileReader in = new FileReader(myFile);
int c;
while((c = in.read()) != -1) {
System.out.print((char) c); // coercion!!
}
in.close();
} catch (FileNotFoundException e) {
System.out.println(“Il file “ +
myFile.getName() + “ non esiste.”);
} catch (IOException e) {
e.printStackFrame();
}
Input / Output
Gianmaria Mancosu
13
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 14
Fondamenti di I/O
l
l
l
l
Uno stream è un flusso di byte o di caratteri
Uno stream di input rappresenta un flusso di
dati provenienti da una sorgente
Uno stream di output rappresenta flusso di dati
verso un consumatore
Esempi di stream sono: i file, la memoria, i
pipe, le socket
Input / Output
Gianmaria Mancosu
14
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 15
Data Streams
l
Java supporta due tipi di stream a seconda del
tipo di dati che vengono trattati
l
l
l
l
Byte stream: rappresentano un flusso di byte
Char stream: vengono trattati i caratteri, codificati
secondo lo standard Unicode
Solitamente con la parola stream si intendono i
flussi di byte
Invece i flussi di caratteri sono gestiti da reader
e writer
Input / Output
Gianmaria Mancosu
15
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 16
Data Streams
l
l
I flussi di byte in input sono gestiti da sottoclassi di
InputStream, mentre quelli in output da OutputStream
I flussi di caratteri in input sono gestiti da sottoclassi
di Reader, quelli in output da Writer
Byte Stream
Char Stream
Input
InputStream
Reader
Output
OutputStream
Writer
Input / Output
Gianmaria Mancosu
16
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 17
Byte Stream: InputStream
l
Metodi di read principali:
l
int read()
l
Restituisce il byte letto. Nel caso di EOF restituisce -1
l
int read(byte[] buffer)
l
Legge dallo stream riempiendo l’array di byte. Restituisce il
numero di byte letti o -1 in caso di EOF
int read(byte[] buffer, int offset, int length)
l
l
Come il precedente, ma partendo dalla posizione
specificata dell’array e per un numero di byte indicato da
length
Input / Output
Gianmaria Mancosu
17
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 18
Byte Stream: OutputStream
l
Metodi di write principali:
l
void write(int c)
l
Scrive il byte specificato nello stream
l
void write(byte[] buffer)
l
Scrive nello stream i byte specificati
void write(byte[] buffer, int offset, int length)
l
l
Come il precedente, ma partendo dalla posizione specificata
dell’array e per un numero di byte indicato da length
Input / Output
Gianmaria Mancosu
18
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 19
Char Stream: Reader
l
Metodi di read principale
l
int read()
l
Restituisce il carattere letto in formato Unicode. Nel caso di
EOF restituisce -1
l
int read(char[] cbuffer)
l
Legge dallo stream riempiendo l’array di caratteri.
Restituisce il numero di caratteri letti o -1 in caso di EOF
int read(char[] cbuffer, int offset, int length)
l
l
Come il precedente, ma partendo dalla posizione specificata
dell’array e per un numero di caratteri indicato da length
Input / Output
Gianmaria Mancosu
19
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 20
Char Stream: Writer
l
Metodi di write principali:
l
void write(int c)
l
Scrive nello stream il carattere Unicode specificato
l
void write(char[] cbuffer)
l
void write(char[] cbuffer, int offset, int length)
l
l
l
l
Scrive nello stream i caratteri specificati
Come il precedente, ma partendo dalla posizione specificata
dell’array e per un numero di caratteri indicato da length
void write(String string)
void write(String string, int offset, int length)
l
Scrive la stringa nel flusso di output
Input / Output
Gianmaria Mancosu
20
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 21
Panoramica di streams
Byte Stream
Char Stream
Classi base
InputStream
OuputStream
Reader
Writer
File
FileInputStream
FileOutputStream
FileReader
FileWriter
Array
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
String
Input / Output
StringReader
StringWriter
Gianmaria Mancosu
21
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 22
Reader/Writer
import java.io.*;
public class TestStreams {
public static void main(String[] args) {
try {
FileReader in = new FileReader(“source.txt”);
FileWriter out = new FileWriter(“dest.txt”);
char buffer[] = new char[200];
int nChars;
Uso di un buffer
ampio 200 caratteri
while((nChars = in.read(buffer)) != -1) {
out.write(buffer, 0, nChars);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackFrame();
}
}
}
Input / Output
Gianmaria Mancosu
22
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 23
Parte I: sommario
l
l
Nel package java.io si possono trovare tutte le classi relative
all’input/output
Java mette a disposizione alcuni stream già aperti:
l
l
l
l
l
l
System.in: InputStream aperto sullo standard input
System.out: PrintStream aperto sullo standard ouput
Per scrivere su System.out si usa il metodo “sovraccarico” println()
Gli oggetti di tipo File sono rappresentazioni astratte di oggetti del
file system
Per leggere o scrivere in un file si possono usare le classi
FileReader e FileWriter
I flussi di dati (stream) sono di due tipi a seconda del tipo di dato
trasmesso:
l
l
Byte stream: flussi di byte (InputStream, OutputStream)
Character stream: flussi di caratteri (Reader, Writer)
Input / Output
Gianmaria Mancosu
23
Input / Output
Parte II
Corso di Linguaggi di
Programmazione ad Oggetti 1
A.A. 2003/04
A cura di
Gianmaria Mancosu
24
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 25
Reader/Writer
import java.io.*;
public class TestStreams {
public static void main(String[] args) {
try {
FileReader in = new FileReader(“source.txt”);
FileWriter out = new FileWriter(“dest.txt”);
char buffer[] = new char[200];
int nChars;
Uso di un buffer
ampio 200 caratteri
while((nChars = in.read(buffer)) != -1) {
out.write(buffer, 0, nChars);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackFrame();
}
}
}
Input / Output
Gianmaria Mancosu
25
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 26
Buffered Reader/Writer
import java.io.*;
Un BufferedReader
public class TestStreams {
public static void main(String[] args) {
contiene un FileReader
try {
FileReader in
= new FileReader(“source.txt”);
BufferedReader buffIn = new BufferedReader(in);
FileWriter out
= new FileWriter(“dest.txt”);
BufferedWriter buffOut = new BufferedWriter(out);
String line;
while((line = buffIn.readLine()) != null) {
buffOut.write(line + “\n”);
}
buffIn.close();
buffOut.close();
} catch (IOException e) {
e.printStackFrame();
}
Lettura di una riga
alla volta: maggiore
efficienza
}
}
Input / Output
Gianmaria Mancosu
26
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 27
I/O Chaining
l
l
l
Raramente in un programma Java si utilizza direttamente uno
stream
Solitamente si creano delle “catene”, ad esempio concatenando
uno stream con uno stream bufferizzato (migliora l’efficienza)
Si può ulteriormente aggiungere uno stream a cui viene delegata
la lettura di dati in un determinato formato (es. tipi primitivi)
File
Programma
FileInputStream
Input / Output
BufferedInputStream
DataInputStream
Gianmaria Mancosu
27
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 28
Filter Streams
l
l
l
l
Un filter stream è uno stream che utilizza un altro
stream per leggere i dati (byte o caratteri)
Ad esempio, quando viene chiamato un metodo read
su un filter input stream i dati restituiti provengono
dall’altro stream collegato
Aggiunge o modifica dei comportamenti (behaviour)
dello stream collegato
I dati possono venire filtrati o convertiti in qualche
modo (es. da byte a oggetti durante l’operazione di
serializzazione di un’istanza)
Input / Output
Gianmaria Mancosu
28
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 29
Decorator Pattern
l
l
l
l
La possibilità di estendere dinamicamente il comportamento di
un oggetto viene realizzata mediante l’applicazione del design
pattern “Decorator”
Design Pattern: un modo standard di risolvere un problema
comune
Solitamente un oggetto eredita il proprio comportamento dalle
superclassi, invece il pattern Decorator permette di estendere
dinamicamente il comportamento di un oggetto
Utilizza il meccanismo del polimorfismo e della delegation
(tramite la composizione)
Input / Output
Gianmaria Mancosu
29
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 30
Decorator
applicato agli stream
l
l
l
l
Uno stream può contenere un altro stream a cui
inoltrare le proprie operazioni (delegation)
Lo scopo di questo contenimento è modificare il
comportamento dell’oggetto contenuto
L’oggetto contenuto viene passato al contenitore come
parametro del costruttore
Es.
FileReader in
= new FileReader(“source.txt”);
BufferedReader buffIn = new BufferedReader(in);
Input / Output
Gianmaria Mancosu
30
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 31
Esempio:
La gerarchia OutputStream
OutputStream
out
public class FilterOutputStream
extends OutputStream {
FilterOutputStream
protected OutputStream out;
ZipOutputStream
ç Oggetto
public FilterOutputStream(OutputStream out)
{…}
}
public class ZipOutputStream
extends FilterOutputStream {
public ZipOutputStream(OutputStream out)
{…}
}
Input / Output
Gianmaria Mancosu
31
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 32
Decorator:
uso del polimorfismo
l
l
Ogni classe della gerarchia di OutputStream definisce
un proprio metodo write() che utilizza il corrispondente
metodo dell’oggetto out aggiungendo un
comportamento che dipende dalla classe contenitore
Es.
public class OutputStream {
public void write(byte[] data)
{…}
public class FilterOutputStream
extends OutputStream {
public void write(byte[] data)
{… usa out.write() …}
Input / Output
Gianmaria Mancosu
32
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 33
Esempio: ZipOutputStream
l
l
l
l
Questa classe appartiene al package java.util.zip
Definisce l’operazione di write comprimendo i byte
che riceve e scrivendoli sullo stream passato nel
costruttore
In altre parole ZipOutputStream aggiunge il
comportamento di compressione dati all’oggetto
OutputStream che riceve
Esempio:
FileOutputStream file = new FileOutputStream(“test.zip”);
ZipOutputStream zip = new ZipOutputStream(file);
zip.write(data);
zip.close();
Input / Output
Gianmaria Mancosu
33
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 34
Byte Stream Hierarchy
FileInputStream
BufferedInputStream
InputStream
ObjectInputStream
DataInputStream
FilterInputStream
LineNumberInputStream
FileOutputStream
BufferedOutputStream
OutputStream
ObjectOutputStream
DataOutputStream
FilterOutputStream
PrintStream
Input / Output
Gianmaria Mancosu
34
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 35
Classi per Byte Stream
l
FileInputStream e FileOutputStream
l
l
Queste classi forniscono i metodi per leggere e
scrivere byte su un file
Il costruttore richiede un’istanza di File oppure il
nome del file da aprire
Input / Output
Gianmaria Mancosu
35
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 36
Classi per Byte Stream
l
BufferedInputStream e BufferedOutputStream
l
l
l
l
Sono dei filter stream
Utilizzano lo stream collegato (passato nel
costruttore) per disaccoppiare le operazioni effettive
di read/write dalle chiamate dei metodi
I metodi di read/write utilizzano un buffer allocato in
memoria per migliorare l’efficienza
Le operazioni di lettura/scrittura effettive vengono
posticipate fino a quando il buffer è pieno o viene
chiamato il metodo flush()
Input / Output
Gianmaria Mancosu
36
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 37
Classi per Byte Stream
l
DataInputStream e DataOutputStream
l
l
l
Sono dei filter stream
Raggruppano i byte letti dallo stream collegato
(passato nel costruttore) in modo da rappresentare
tipi Java primitivi
Esempi di metodi:
l
l
l
l
readByte()
readLong()
writeByte()
writeLong()
Input / Output
Gianmaria Mancosu
37
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 38
Char Stream Hierarchy
Reader
BufferedReader
LineNumberReader
InputStreamReader
FileReader
FilterReader
PushbackReader
BufferedWriter
Writer
OutputStreamWriter
FileWriter
FilterWriter
Input / Output
Gianmaria Mancosu
38
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 39
Classi per Char Stream
l
InputStreamReader e OutputStreamWriter
l
l
l
l
Sono i più importanti discendenti di Reader e Writer
Sono usati come interfaccia tra gli stream di byte e
quelli di caratteri
I byte vengono convertiti in caratteri specificando le
regole di conversione (di default è Unicode)
Nel costruttore occorre specificare l’InputStream o
l’OutputStream da cui vengono letti/scritti i byte
Input / Output
Gianmaria Mancosu
39
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 40
Classi per Char Stream
l
FileReader e FileWriter
l
l
l
Derivano da InputStreamReader e
OutputStreamReader
Rappresentano gli analoghi per char stream di
FileInputStream e FileOutputStream
BufferedReader e BufferedWriter
l
l
Rappresentano gli analoghi per char stream di
BufferedInputStream e BufferedOutputStream
Aumentano l’efficienza nella gestione di flussi di
caratteri
Input / Output
Gianmaria Mancosu
40
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 41
Classi per Char Stream
l
StringReader e StringWriter
l
l
Derivano da Reader e Writer usando come flusso di
input/output una stringa passata come parametro
del costruttore
In particolare StringWriter utilizza uno StringBuffer
che rende efficiente l’aggiunta ad una stringa di un
carattere alla volta
Input / Output
Gianmaria Mancosu
41
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 42
New I/O:
the java.nio package
l
La versione delle API Java 1.4 hanno aggiunto nuove
funzionalità di I/O di più alto livello
l
Canali
l
l
l
l
Rappresenta una connessione tra un oggetto software e un
dispositivo hardware di I/O, un file, un socket
Può essere gestito in maniera asincrona
Le classi e le interfacce che riguardano i canali si trovano nel
package java.nio.channels
Buffer
l
l
l
Rappresenta un contenitore di dati primitivi
È direttamente associabile ad un file
Permette la navigazione tramite i metodi get() e put() assoluti
o relativi
Input / Output
Gianmaria Mancosu
42
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 43
New I/O:
the java.nio package
l
Charset
l
l
l
Rappresenta un set di caratteri definito secondo uno
standard (es. Unicode, UTF-8, ISO-8859-1)
Reso necessario dallo sviluppo di applicazioni
internazionali su Internet
Nel package java.nio.charsets possiamo trovare i coder
e i decoder che trasformano flussi di byte in caratteri
secondo lo standard specificato:
§
§
Input / Output
CharsetEncoder
CharsetDecoder
Gianmaria Mancosu
43
Corso di Linguaggi di Programmazione ad Oggetti - 1
Slide 44
Parte II: sommario
l
l
l
l
Tramite l’I/O chaining Java consente di modificare il
comportamento standard degli stream
Implementazione del design pattern Decorator, che utilizza
polimorfismo e delegation per estendere il comportamento degli
oggetti dinamicamente
Le classi InputStreamReader e OutputStreamWriter
rappresentano l’interfaccia tra gli stream di byte e quelli di
caratteri
La versione 1.4 delle Java API hanno aggiunto una serie di classi
che trattano gli stream ad un livello più alto e più moderno
(Internet, internazionalizzazione) aggiungendo buffer, channel,
charset nel package java.nio e suoi sottopackage
Input / Output
Gianmaria Mancosu
44