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