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.