Java I/O
Corso di Programmazione
CdS: Informatica e Tecnologie
per la Produzione di Software
Nicola Fanizzi
[email protected]
Introduzione
2
 Spesso un programma deve acquisire dati
da una sorgente o inviare informazioni a
una destinazione (esterne)
 L’informazione può essere di ogni tipo:




caratteri
immagini
suoni
oggetti
 Librerie java.io (e la nuova java.nio)
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classe File

3
Serve per ottenere informazioni riguardo un file
NB: Creare un oggetto di tipo File non significa creare un file fisico
Costruttori
 File(String percorso)
Crea un oggetto di tipo File a partire da una stringa (il percorso)

File(File dir, String nome)
Crea un oggetto di tipo File denominato nome a partire dalla directory dir
(descritta tramite un oggetto di tipo File)

File(String dir, String nome)
Crea un oggetto di tipo File denominato nome a partire dalla directory dir
(descritta tramite una stringa)
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Esempio
4
Uso di File
1.
2.
import java.io.File;
true
true
false
true
true
919
C:\Prove\FileInfo .class
FileInfo.class
null
C:\Prove
public class FileInfo {
4.
public static void main(String[] args)
5.
throws java.io.IOException {
6.
File f = new File("FileInfo.class");
7.
System.out.println(f.exists());
8.
System.out.println(f.isFile());
9.
System.out.println(f.isDirectory());
10.
System.out.println(f.canRead());
11.
System.out.println(f.canWrite());
12.
System.out.println(f.length());
13.
System.out.println(f.getAbsolutePath());
14.
System.out.println(f.getName());
15.
System.out.println(f.getParent());
16.
File p = new File(f.getAbsolutePath());
17.
System.out.println(p.getParent());
18.
}
19. }
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
3.
File
Metodi
Metodi Utili
 boolean delete()
Cancella il file o la directory specificata

boolean mkdir()
Crea la directory

boolean renameTo(File dest)
Cambia nome al file

String[] list()
Restituisce un vettore con i nomi dei file della directory dall’oggetto File

File[] listFiles()
Restituisce un vettore con gli oggetti File che fanno file della directory
riferita dall’oggetto File
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
5
Esempio
Listato Directory
1.
import java.io.File;
2.
3.
public class Lista {
4.
5.
6.
7.
8.
9.
10.
11.}
public static void main(String[] args) {
File workingDir = new File(".");
String[] lista = workingDir.list();
for(int i=0; i<lista.length; i++)
System.out.println(lista[i]);
}
Lista.java
Lista.class
Copy.java
Copy.class
FileInfo.java
FileInfo.class
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
6
Input / Output
7
scrittura
applicazione
sorgente
lettura
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
destinazione
Flussi di Input / Output
8

Per acquisire dati, una applicazione deve aprire uno
stream (o flusso) associato alla sorgente di
informazione (file, socket, memoria, ecc.) e leggere
l’informazione sequenzialmente da esso

Un programma può inviare verso una destinazione
esterna dei dati aprendo uno stream associato alla
destinazione e scrivendovi in modo sequenziale i dati

Indipendentemente dall’origine e dalla destinazione dei
dati e dal loro tipo, gli algoritmi per leggere e scrivere
sequenzialmente dei dati sono molto simili
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Lettura / Scrittura Sequenziale
Lettura
Apertura dello stream
Finché ci sono dati da
leggere
lettura dato
Chiusura dello stream
Scrittura
Apertura dello stream
Finché ci sono dati da
scrivere
scrittura dato
Chiusura dello stream
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
9
Tipi di Flusso

Le classi di gestione degli stream sono di due tipi in base
ai dati su cui operano: caratteri / byte



Stream di Caratteri (Unicode 16bit)
classi Reader e Writer e derivate
Stream di Byte (8bit)
classi InputStream e OutputStream e derivate
Esistono varie sottoclassi che consentono la
lettura/scrittura su file come, ad es.:



10
FileReader e FileWriter (testo)
FileInputStream e FileOutputStream (binari)
Possono sollevare eccezioni della classe IOException
(e sue derivate)
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Tipi di Flusso






11
Le classi astratte Filter- rappresentano i flussi ai quali è applicato
una forma di filtraggio man mano che essi vengono letti/scritti
I flussi Buffered- aggiungono ad ogni flusso un buffer per
aumentare l'efficienza
I flussi Piped- vengono progettati a coppie in modo da poterle
collegare
I flussi di memoria permettono di utilizzare strutture dati presenti in
memoria come sorgenti/destinazioni di informazione
I flussi Print- permettono di controllare la formattazione
dell'output
Altri flussi: utili alla costruzione di parser



PushbackInputStream
LineNumberInputStream
StreamTokenizer
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classi dei Flussi di Byte 12
frammento
FileInputStream
InputStream
PipedInputStream
DataInputStream
FilterInputStream
BufferedInputStream
ByteArrayInputStream
PushbackInputStream
SequenceInputStream
LineNumberInputStream
StringBufferInputStream
ObjectInputStream
gerarchia analoga
per OutputStream
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
13
InputStream
abstract int read()

legge il prossimo byte di dati dallo stream
int read(byte[] b)

legge i prossimi byte di dati dallo stream salvandoli nel buffer array b
int read(byte[] b, int off, int len)

legge len byte dallo stream salvandoli nell'array b a partire da off
void reset()

riposiziona lo stream all’ultima marcatura provocata da mark()
long skip(long n)

salta i prossimi n byte letti dallo stream
int available()

restituisce il numero di byte leggibili da questo stream
void mark(int readlimit)

marca la posizione corrente
boolean markSupported()

Testa se lo stream supporta i metodi mark e reset
void close()

Corso di Programmazione
© 2004 S.Ferilli
& N.Fanizzi - dib - UniBA
chiude lo stream
e rilascia (IPSW)
le risorse
associate
Esempio 14
Conteggio Byte Letti da Stream
1.
import java.io.*;
2.
public class ContaByte {
4.
public static void main(String[] args)
throws IOException {
5.
InputStream in = new FileInputStream(args
[0]);
6.
int totale;
7.
while (in.read() != -1)
8.
++totale;
9.
System.out.pritln(“Letti: ”+totale+” byte”);
10.
in.close();
11.
}
12. }
3.
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
15
OutputStream
abstract void write(int b)

scrive il byte specificato sullo stream
void write(byte[] b)

scrive i b.length byte dell'array specificato sullo stream
void write (byte[] b, int off, int len)

scrive sullo stream len byte dell'array specificato iniziando da
offset
void flush()

svuota lo stream, forzando la scrittura dei byte ancora nel buffer
void close()

chiude lo stream rilasciando le risorse associate
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classi dei Flussi di Caratteri 16
frammento
BufferedReader
LineNumberReader
CharArrayReader
InputStreamReader
FileReader
FilterReader
PushBackReader
Reader
PipedReader
StringReader
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
gerarchia analoga
per Writer
17
Reader
abstract void close()
 chiude il flusso
void mark(int readAheadLimit)
 marca la posizione corrente
boolean markSupported()
 dice se lo stream supporta la marcatura
int read()
 legge un carattere
int read(char[] cbuf)
 legge caratteri in un array
abstract int read(char[] cbuf, int off, int len)
 legge caratteri in una porzione di array
int read(CharBuffer target)
 cerca di leggere caratteri nel buffer di caratteri specificato
boolean ready()
 dice se lo stream è pronto per nuove letture
void reset()
 resetta lo stream
long skip(long n)
 salta n caratteri
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Esempio 18
Lettura da Reader
1.
import java.io.*;
2.
3.
4.
5.
6.
public class ContaSpazi {
public static void main(String[] args)
throws IOException {
Reader in = new FileReader(args[0]);
int totale = 0, spazi = 0, ch;
7.
while (in.read() != -1) {
++totale;
if (Character.isWhiteSpace((char)ch))
++spazi;
}
System.out.pritln("spazi:"+spazi+“/”+totale);
in.close();
8.
9.
10.
11.
12.
13.
14.
}
15.
16.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
19
Writer
Writer append(char c)
 aggiunge il carattere specificato allo stream
Writer append(CharSequence csq)

aggiunge i caratteri specificati nella sequenza allo stream
Writer append(CharSequence csq, int start, int end)

aggiunge allo stream i caratteri specificati nella sotto-sequenza
abstract void close()

chiude lo stream dopo lo svuotamento
abstract void flush()
 svuota lo stream
void write(char[] cbuf)
 scrive un array di caratteri
abstract void write(char[] cbuf, int off, int len)
 scrive una porzione di un array di caratteri
void write(int c)
 scrive un carattere
void write(String str)
 scrive una stringa
void write(String str, int off, int len)
 scrive una porzione di una stringa
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
InputStreamReader 20
OutputStreamWriter

Permettono la conversione da flusso caratteri Unicode a
flusso di byte e viceversa:
InputStreamReader(InputStream in)

la sorgente in fornisce un flusso di byte che viene convertito in
un flusso di caratteri
char read()

legge il prossimo carattere dal flusso di byte collegato
OutputStreamWriter(OutputStream out)

fornisce la conversione di un flusso di caratteri in un flusso di
byte di destinazione out
write(char c)

scrive il carattere sul flusso di byte collegato
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
21
FileReader
public FileReader(String nomeFile)
throws FileNotFoundException
Crea un nuovo FileReader, per leggere dal file il
cui nome viene passato
 Parametri:


nomeFile
nome del file da leggere
Eccezioni:

FileNotFoundException
se il file specificato non esiste
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Lettura
22
Per leggere caratteri da un file si crea un’istanza FileReader
FileReader(String nomeFile)
esempio:
FileReader myReader = new FileReader(“input.txt”);

Per leggere sequenze di byte da un file si crea un’istanza di
FileInputStream
FileInputStream(String nomeFile)
esempio:
FileInputStream myInputStream =
new FileInputStream(“input.txt”);


In entrambi i casi si utilizza il metodo int read() che legge un carattere /
byte per volta e restituisce un valore di tipo int che corrisponde al codice
del carattere / byte letto oppure –1 se non ci sono più dati da leggere
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Copia di un File di Caratteri
1.
import java.io.*;
2.
3.
4.
5.
6.
7.
8.
public class CopiaCaratteri {
public static void main(String[] args)
throws IOException {
FileReader in = new FileReader(args[0]);
FileWriter out = new FileWriter(args[1]);
int c;
9.
while ((c = in.read()) != -1)
out.write(c) ;
10.
11.
12.
in.close();
out.close();
}
13.
14.
15.
16.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
23
Copia di un File di Byte
1.
24
import java.io.*;
2.
3.
4.
5.
6.
7.
8.
public class CopiaByte {
public static void main(String[] args)
throws IOException {
FileInputStream in = new FileInputStream(args[0]);
FileOutputStream out = new FileOutputStream(args[1]);
int c;
9.
while ((c = in.read()) != -1)
out.write(c) ;
10.
11.
12.
in.close();
out.close();
}
13.
14.
15.
16.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Stream con Buffer
25
migliora le performance dell'I/O
 copia ogni input/output da/verso una regione di
memoria detta buffer
 lettura/scrittura dell'intero buffer su disco in
un'unica soluzione


un'unica sessione di accesso a disco impiega meno di
tanti piccoli accessi
BufferedOutputStream
file output bufferizzato
 BufferedInputStream
file input bufferizzato

Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
26
BufferedReader

Conente di gestire un flusso tramite un buffer (area di memoria)


I dati vengono letti a blocchi dal flusso e memorizzati in un buffer.
Quando viene richiesto un nuovo dato,
prima si verifica la sua disponibilità nel buffer e,
se non disponibile in memoria, si legge un nuovo blocco dal flusso
Costruttori disponibili
BufferedReader(Reader in)
Crea un oggetto BufferedReader a partire da un oggetto Reader

Metodi disponibili in aggiunta a quelli di Reader
String readLine()
Legge una riga e la restituisce sotto forma di stringa

Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
BufferedReader 27
Lettura
FileReader file = new FileReader(“nome-file”);
BufferedReader in = new BufferedReader(file);
oppure
BufferedReader in = new BufferedReader(new
FileReader(“nome-file”));
in.readLine();
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
BufferedReader 28
Esempio
1.
import java.io.*;
2.
public class TestLettura {
4.
public static void main(String[] args)
5.
throws IOException {
6.
FileReader file = new FileReader(args[0]);
7.
BufferedReader in = new BufferedReader(file);
8.
String linea;
9.
while ((linea = in.readLine()) != null)
10.
System.out.println(linea);
3.
11.
12.
13.
in.close();
}
14. }
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classe PrintWriter


29
La classe PrintWriter mette a disposizione i metodi

void print()

void println()
utilizzabili con qualunque tipo di parametro
(stringa, intero, reale, ecc.)
Si può creare un nuovo oggetto PrintWriter a partire
da un Writer, in particolare da un FileWriter
esempio:
PrintWriter f = new PrintWriter(
new FileWriter(“nome-file”));
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
30
Scrittura su PrintWriter
1.
import java.io.*;
2.
public class TestCopia {
4. public static void main(String[] args)
5.
throws IOException {
6.
FileReader file = new FileReader(args[0]);
7.
BufferedReader in = new BufferedReader(file);
8.
String line;
9.
PrintWriter out =
new PrintWriter (new FileWriter(args[1]));
10.
while ((line = in.readLine()) != null)
11.
out.println(line);
3.
12.
in.close();
out.close();
}
13.
14.
15.
16.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classe PrintStream
31
La classe PrintStream mette a disposizione i metodi
void print() e void println() utilizzabili con
qualunque tipo di parametro (stringa, intero, reale, ecc.)
 Si può creare un nuovo oggetto PrintStream a partire
da un OutputStream, in particolare da un
FileOutputStream
PrintStream f =
new PrintStream(new
FileOutputStream
(“file.dat”));


System.out e System.err sono di tipo
PrintStream
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
32
Scrittura su PrintStream
1.
import java.io.*;
2.
public class TestCopia {
4.
public static void main(String[] args)
5.
throws IOException {
6.
FileReader file = new FileReader(args[0]);
7.
BufferedReader in = new BufferedReader(file);
8.
String line;
9.
PrintStream out =
new PrintStream(new FileOutputStream(args[1]));
10.
while ((line = in.readLine()) != null)
11.
out.println(line);
3.
12.
in.close();
out.close();
}
13.
14.
15.
16.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Esempio 33
Uso degli Stream
import java.io.*;
2. public class TestLetturaVettore {
3.
public static void main(String[] args)
4.
throws IOException {
5.
if (args.length < 1) System.exit(-1);
6.
FileReader myFile = new FileReader(args[0]);
7.
BufferedReader in = new BufferedReader(myFile);
8.
int i = 0, v[] = new int[100], dim;
9.
String linea;
10.
while (i < 100 && (linea = in.readLine()) != null){
11.
v[i] = Integer.parseInt(linea);
12.
i++;
13.
}
14.
dim = i;
15.
for(i=0; i<dim; i++)
16.
System.out.println(v[i]);
17.
in.close();
18.
}
19. }
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
1.
Esempio 34
Uso di Stream
1.
2.
public class VettoreInt {
private int v[] = new int[100], dim;
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public void leggi(String nomeFile)
throws IOException {
FileReader file = new FileReader (nomeFile);
BufferedReader in = new BufferedReader(file);
int i = 0;
String line;
while (i < 100 && (line = in.readLine()) != null){
v[i] = Integer.parseInt(line);
i++;
}
dim = i;
in.close();
} // fine metodo leggi
16.
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Esempio 35
Uso di Stream
1.
2.
3.
4.
5.
6.
public void stampa( String nomeFile)
throws IOException {
PrintWriter out =
new PrintWriter(new FileWriter (nomeFile));
for(int i=0; i<dim; i++)
out.println(v[i]);
out.close();
} // fine metodo stampa
7.
public static void main(String[] args)
throws IOException {
9.
if(args.length < 2) {
10.
System.out.println("errore");
11.
System.exit (-1);
12.
}
13.
VettoreInt myData = new VettoreInt ();
14.
myData.leggi(args[0]);
15.
myData.stampa(args[1]);
16.
} // fine metodo main
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
17. } // fine classe
8.
Classe System


Consente l’accesso a risorse del sistema come lo standard
output, allo standard input, ecc.
Fornisce




36
stream in (di tipo InputStream) associato allo standard input,
stream out (di tipo PrintStream) associato all’output e
stream err associato allo standard error.
Inoltre contiene alcuni metodi che svolgono diversi
compiti, ad esempio:

metodo exit(int status) interrompe l’interpretazione del
programma, ecc.
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
File di Record

Record



composti da diversi campi
implementabili come oggetti Java
Un file può essere visto come un gruppo di
record correlati


Un campo di ogni record è la chiave
file sequenziale
record immagazzinati in ordine di chiave

File di record in Java


Java non impone alcuna struttura ai file
Il programmatore dà una struttura ai file a seconda
dell'applicazione
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
37
Record
Judy
1
Black
Tom
Blue
Judy
Green
Iris
Orange
Randy
Red
Green
Judy
codice
01001010
ASCII J
Sally
File
Record
Campo
Byte
Bit
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
38
File e Flussi
39
 Java vede i file come flussi di byte
 Un file termina con un marcatore di end-
of-file

File come flussi di byte associati ad oggetto
 Elaborazione file con le classi di java.io




FileInputStream
FileOutputStream
FileReader
FileWriter
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
File ad Accesso Sequenziale 40
Aggiornamento
 Difficile aggiornare file ad accesso
sequenziale


L'intero file deve essere riscritto per cambiare
un singolo campo
Accettabile solo quando tanti record devono
essere aggiornati alla volta
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
File ad Accesso Casuale

Applicazioni con accesso in tempo reale



41
Record da collocare immediatamente
Sistemi a transazioni: richiedono tempi rapidi
d'accesso
File ad accesso casuale (random)


Si accede a record individuali in modo diretto e rapido
lunghezza fissa per ogni record
facilità di calcolo delle posizioni

inserimento senza distruzione degli altri dati del file
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
File ad Acceso Casuale 42
Schema
0
100
byte
100
200
300
400
500
100
byte
100
byte
100
byte
100
byte
100
byte
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
offset in
byte
43
RandomAccessFile

RandomAccessFile(String n, String m)
throws FileNotFoundException


prima stringa: nome di file fisico
seconda: modo di accesso
lettura: modo read “r”
Lancio IOException se in questa modalità non esiste il file o si
tratta di una directory
lettura e scrittura: modo “rw”.
In modalità “rw” se non esiste lo crea, se esiste si predispone per le
operazioni di lettura o scrittura ponendo il puntatore all’inizio


simile a DataInputStream e DataOutputstream
legge/scrive dati in locazioni specificate dal puntatore di
posizione nel file


Manipola i dati come fossero di tipi primitivi
Normalmente si scrive su file un oggetto per volta
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
44
RandomAccessFile
Metodi
long length()

Restituisce il numero di byte del file.
void setLength(long newLength)

Setta la lunghezza del file.
se il file e più corto lo amplia,
se più lungo lo tronca.

In caso di riscrittura su un file esistente è necessario utilizzare
questo metodo al termine della scrittura per inserire l’eof.
Nella forma setLength(getFilePointer())
long getFilePointer()

Restituisce la posizione in byte del puntatore attuale
void seek(long pos)

Porta il puntatore sul byte di posizione indicata
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
45
RandomAccessFile
...
void close()

Chiude il file e libera la memoria heap
long readLong()
double readDouble()

Legge un dato e trasla il puntatore di una quantità pari al numero
di byte binari occupati dal tipo di dato. La lettura produce un
EOFException quando incontra il termine del File
String readLine()



in scrittura è a carico del programmatore aggiungere un carattere
di fine linea ‘\r’ o ‘\n’ o entrambi.
Legge tutti i caratteri fino al marcatore di fine linea ‘\r’ o ‘\n’
Se il puntatore è a EOF la stringa acquisita è null. In ogni caso si
produce un EOFException
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
46
RandomAccessFile
...
void
void
void
void
void
void
void

writeInt(int)
writeLong(long)
writeDouble(double)
writeFloat(float)
writeByte(int)
writeBoolean(boolean)
writeChar(int)
Scrive il dato indicato e trasla il puntatore.
void writeBytes(String)
void writeChars(String)

Scrive tutti i byte di una stringa in formato dipendente dalla
macchina.
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Persistenza degli Oggetti



Possibilità di immagazzinare e recuperare oggetti anche
complessi
Gli oggetti vengono immagazzinati in uno stream
Bisogna decidere un certo protocollo di memorizzazione.
Si codificano tali caratteristiche


usando le stringhe ed usando numeri
Le cose sono difficili se la struttura dati è complessa:


47
Occorre implementare due metodi di conversione della struttura
in forma sequenziale, salvarla per poi ripristinarla, ricostruendo
la struttura originaria
Due soluzioni:


serializzazione
esternalizzazione
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Serializzazione
48
Serializable


Interfaccia che deve essere realizzata dagli oggetti da serializzare
L’oggetto serializzato contiene tutta l’informazione necessaria per




verificare la sua classe
per ricostruirne l’istanza
L’operazione di memorizzazione di oggetti in un flusso
viene detta Serializzazione
Ogni oggetto riceve un numero di serie:


Se lo stesso oggetto viene salvato due volte, la seconda volta ne
viene salvato solo il numero di serie
Se in un flusso si incontra più volte lo stesso numero di serie,
questi vengono interpretati come riferimenti allo stesso oggetto
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Esternalizzazione
49
Externalizable



Interfaccia che deve essere realizzata dagli oggetti da
“esternalizzare”
Realizza l’interfaccia Serializable...
... ma l’oggetto esternalizzabile è l’unico responsabile del
formato esterno dei suoi contenuti
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Interfaccia Serializable


50
Se un oggetto implementa l’interfaccia Serializable,
esso è serializzabile cioè può essere reso persistente e poi
ripristinato
La cosa importante è che l’oggetto ripristinato abbia le
stesse proprietà dell’oggetto salvato


possibilità di definire alcune proprietà come transient:
viene salvata l’istanza ma in fase di ripristino i suoi campi
assumono i loro valori di default
Supponendo di avere una classe di nome Struttura,
per renderla serializzabile basterà scrivere:
public class Struttura
implements Serializable {
...
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Serializzazione di Oggetti
ObjectOutput
Interfaccia: un contenitore in cui
possono essere immagazzinati
oggetti
 writeObject(Object o)
 writeInt(), writeFloat
(), ...
 flush()
ObjectOutputStream
 Realizza l’interfaccia
ObjectOutput
 Costruita a partire da un
OutputStream
51
ObjectInput
Interfaccia: un contenitore da cui
possono essere recuperati
oggetti
 Object readObject()
 readInt(), readFloat
(), ...
ObjectInputStream
 Realizza l’interfaccia
ObjectInput
 Costruita a partire da un
InputStream
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Serializzazione 52
Esempio
public void scrivi () {
try {
s = new ObjectOutputStream(new FileOutputStream("save.ser"));
s.writeObject(salvato);
s.close();
} catch (IOException ioe) { System.out.println
("Errore:"+ioe.toString());
}
}
public void leggi () {
try {
s = new ObjectInputStream(new FileInputStream("save.ser"));
salvato = (TipoSalvato)(s.readObject());
s.close();
} catch (IOException ioe) {
System.out.println("Errore:"+ioe.toString());
}
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Nuove API I/O di Java 53
Buffer
Consolidamento delle operazioni di I/O
 4 proprietà:






Operazioni di put & get


Capacity
Limit
Position
Mark
Relative o assolute
clear, flip, rewind, reset
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Nuove API I/O di Java 54
Canali

Connessione a dispositivi per l'I/O
Interazione efficiente con buffer

interfaccia ReadableByteChannel


Metodo read
interfaccia WriteableByteChannel

Metodo write
lettura sparsa e scrittura raccolta
 Classe FileChannel

Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Nuove API I/O di Java

File Lock




Pone restrizioni all'accesso di una porzione di file
FileChannel, posizione, dimensione
esclusivo o condiviso
Charset

Package java.nio.charset
Class Charset
 Metodi decode, encode
Class CharsetDecoder, CharsetEncoder
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
55
56
FileChannelTest
1.
2.
3.
4.
// FileChannelTest.java
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
5.
6.
7.
public class FileChannelTest {
private FileChannel fileChannel;
8.
9.
10.
11.
12.
13.
14.
15.
public FileChannelTest() {
try {
RandomAccessFile file =
new RandomAccessFile( "Test", "rw" );
fileChannel = file.getChannel();
} catch ( IOException ioException ) {
ioException.printStackTrace();
}
16.
17. }
// end costruttore
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
FileChannelTest 57
continua
1.
2.
public void writeToFile() throws IOException {
ByteBuffer buffer = ByteBuffer.allocate
( 14 );
3.
buffer.putInt( 100 );
buffer.putChar( 'A' );
buffer.putDouble( 12.34 );
4.
5.
6.
7.
buffer.flip();
fileChannel.write( buffer );
8.
9.
10.
}
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
FileChannelTest 58
continua
1.
2.
3.
4.
5.
7.
public void readFromFile() throws IOException {
String content = "";
ByteBuffer buffer = ByteBuffer.allocate( 14 );
fileChannel.position( 0 );
fileChannel.read( buffer );
buffer.flip();
8.
9.
content += buffer.getInt() + ", " +
buffer.getChar() + "," +
buffer.getDouble();
10.
11.
System.out.println( "File contains: " + content );
12.
13.
14.
fileChannel.close();
} // end readFromFile
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
FileChannelTest 59
continua
1.
2.
public static void main( String[] args ) {
FileChannelTest application =
new FileChannelTest();
3.
4.
5.
6.
7.
8.
9.
10.
11.
try {
application.writeToFile();
application.readFromFile();
}
catch ( IOException ioException ) {
ioException.printStackTrace();
}
} // metodo
12.
13.
} // end class FileChannelTest
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
60
StringTokenizer
La classe StringTokenizer è definita nel
package java.util
 Un oggetto StringTokenizer separa una
stringa in sottostringhe dette token
 Per default, il tokenizer separa la stringa ad ogni
spazio
 Il costruttore di StringTokenizer richiede
come parametro la stringa da separare.
 Ciascuna chiamata al metodo nextToken()
restituisce il token successivo

Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
Classe StringTokenizer
Costruttori
 StringTokenizer(String str)
Costruisce un tokenizer per la stringa specificata.

StringTokenizer(String str, String delim)
Constructs a string tokenizer for the specified string
Metodi
 int countTokens()
Calcola il numero di volte che il metodo nextToken() del tokenizerpuò
essere chiamato prima di generare un’eccezione

boolean hasMoreTokens()
Testa se ci sono ancora token nella stringa da analizzare

String nextToken()

restituisce il prossimo token dalla stringa in esame
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
61
Esempio 62
Uso di StringTokenizer
import java.io.*;
2. import java.util.*;
3. public class testLetturaToken {
4.
public static void main(String[] args)
5.
throws IOException {
6.
FileReader file = new FileReader(args[0]);
7.
BufferedReader in = new BufferedReader(file);
8.
String linea;
9.
while ((linea = in.readLine()) != null) {
10.
StringTokenizer st =
new StringTokenizer(linea);
11.
while(st.hasMoreTokens())
12.
System.out.println(st.nextToken());
13.
}
14.
in.close();
15.
} // metodo
16. } // classe
Corso di Programmazione (IPSW) © 2004 S.Ferilli & N.Fanizzi - dib - UniBA
1.