Input / Output Spesso un programma deve acquisire dati da una sorgente esterna o inviare informazioni a una destinazione esterna. L’informazione può essere di ogni tipo: caratteri, immagini, suoni, oggetti. 1 Input / Output Stream di Input / Output Per acquisire dati, un programma apre uno stream associato alla sorgente di informazione (file, socket, memoria, ecc.) e legge l’informazione sequenzialmente da esso. In modo analogo, un programma puo’ 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 gli stessi. 2 Stream di Input / Output 3 Input / Output Lettura Apertura dello stream Finché e’ presente informazione leggi l’informazione Chiusura dello stream Scrittura Apertura dello stream Finché e’ presente informazione scrivi l’informazione Chiusura dello stream 4 Tipi di Stream Le classi di gestione degli stream sono di due tipi in base ai dati su cui operano (caratteri/byte). Stream di Caratteri: classi Reader e Writer Stream di Byte: classi InputStream e OutputStream (di solito usati per leggere file di immagini e suoni). Esistono varie sottoclassi che consentono la lettura/scrittura su file: FileReader e FileWriter (file di testo) FileInputStream e FileOutputStream (file binari). 5 Gestione di Stream di caratteri 6 Gestione di Stream di byte 7 java.lang.Object | +--java.io.Reader | +--java.io.InputStreamReader | +--java.io.FileReader FileReader public FileReader(String fileName) throws FileNotFoundException Crea un nuovo FileReader, per leggere dal file il cui nome viene passato come parametro. Parametri: FileName – nome del file da leggere Throws: FileNotFoundException – se il file specificato non esiste 8 Classi FileReader e FileInputStream Per leggere caratteri da un file si crea un oggetto di tipo FileReader. FileReader(String fileName) Esempio: FileReader reader = new FileReader(“input.txt”); Per leggere sequenze di byte da un file si crea un oggetto di tipo FileInputStream. FileInputStream(String name) Esempio: FileInputStream inputStream = 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. Tale valore corrisponde al codice del carattere / byte letto oppure –1 se non ci sono più dati da leggere. 9 Scrittura di dati su file Scrittura Si utilizzano analogamente le classi FileWriter e FileOutputStream per scrivere in un file sequenze di caratteri/byte. FileWriter writer = new FileWriter (“output.txt”); FileOutputStream outputStream = new FileOutputStream (“output.txt”); In entrambi i casi si utilizza il metodo void write(int c) che scrive un carattere/byte per volta. Tale valore corrisponde al codice del carattere / byte da scrivere nel file. Chiusura di un file Dopo avere letto/scritto tutti i dati nel file, questo deve essere chiuso con il metodo void close(). 10 Copia di un file • • • • • • • • • • • • • • • • import java.io.*; public class CopyChars { public static void main(String[] args) throws IOException { FileReader in = new FileReader(args[0]); FileWriter out = new FileWriter(args[1]); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } } 11 Copia di un file • • • • • • • • • • • • • • • • import java.io.*; public class CopyBytes { public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream(args[0]); FileOutputStream out = new FileOutputStream(args[1]); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } } 12 Classe BufferedReader Un BufferedReader permette di gestire un flusso tramite un buffer: I dati vengono letti a blocchi dal flusso e memorizzati in un buffer (area di memoria). 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. 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 13 Lettura • • • • • • • • • • • • • • import java.io.*; public class testLettura { public static void main(String[] args) throws IOException { FileReader file = new FileReader(args[0]); BufferedReader in = new BufferedReader(file); String line; while ((line = in.readLine()) != null) System.out.println(line); in.close(); } } 14 Classe PrintWriter La classe PrintWriter 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 PrintWriter a partire da un Writer, in particolare da un FileWriter. PrintWriter f = new PrintWriter ( new FileWriter (“nome-file”) ); 15 Scrittura • • • • • • • • • • • • • • • • import java.io.*; public class testCopia { public static void main(String[] args) throws IOException { FileReader file = new FileReader(args[0]); BufferedReader in = new BufferedReader(file); String line; PrintWriter out = new PrintWriter (new FileWriter(args[1])); while ((line = in.readLine()) != null) out.println(line); in.close(); out.close(); } } 16 Classe PrintStream 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(“nome-file”) ); Gli oggetti System.out e System.err sono di tipo PrintStream 17 Scrittura • • • • • • • • • • • • • • • • import java.io.*; public class testCopia { public static void main(String[] args) throws IOException { FileReader file = new FileReader(args[0]); BufferedReader in = new BufferedReader(file); String line; PrintStream out = new PrintStream(new FileOutputStream(args[1])); while ((line = in.readLine()) != null) out.println(line); in.close(); out.close(); } } 18 Classe StringTokenizer La classe StringTokenizer class e’ 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 StringTokenizer richiede come parametro la stringa da separare. Ciascuna chiamata al metodo nextToken restituisce il token successivo. 19 Classe StringTokenizer Constructor Summary StringTokenizer(String str) Constructs a string tokenizer for the specified string. StringTokenizer(String str, String delim) Constructs a string tokenizer for the specified string. Method Summary int countTokens() Calculates the number of times that this tokenizer's nextToken method can be called before it generates an exception. boolean hasMoreTokens() Tests if there are more tokens available from this tokenizer's string. String nextToken() Returns the next token from this string tokenizer. 20 Lettura token 1. 2. import java.io.*; 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 line; 9. while ((line = in.readLine()) != null) { 10. StringTokenizer st = new StringTokenizer(line); 11. while(st.hasMoreTokens()) 12. System.out.println(st.nextToken()); 13. } 14. in.close(); 15. } 16. } 21 Classe File Serve per ottenere informazioni riguardo un file, non tratta file aperti Nota bene: Creare un oggetto di tipo File non significa creare un file fisico Costruttori disponibili File(String pathname) Crea un oggetto di tipo File a partire da una stringa (il pathname) File(File parent, String child) Crea un oggetto di tipo File avente come nome child a partire dalla directory parent (descritta tramite un oggetto di tipo File) File(String parent, String child) Crea un oggetto di tipo File avente come nome child a partire dalla directory parent 22 Proprietà di un file 1. import java.io.File; 2. 3. public class FileInfo { 4. 5. public static void main(String[] args) 6. throws java.io.IOException { 7. File f = new File("FileInfo.class"); 8. System.out.println(f.exists()); 9. System.out.println(f.isFile()); 10. System.out.println(f.isDirectory()); 11. System.out.println(f.canRead()); 12. System.out.println(f.canWrite()); 13. System.out.println(f.length()); 14. System.out.println(f.getAbsolutePath()); 15. System.out.println(f.getName()); 16. System.out.println(f.getParent()); 17. File p = new File(f.getAbsolutePath()); 18. System.out.println(p.getParent()); 19. } 20. } true true false true True 919 E:\Prove\FileInfo.class FileInfo.class null E:\Prove 23 File Metodi disponibili 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 riferita dall’oggetto File File[] listFiles() Restituisce un vettore con gli oggetti File che fanno riferimento ai file della directory riferita dall’oggetto File … 24 Listato di una directory 1. import java.io.File; 2. 3. public class Lista { 4. 5. public static void main(String[] args) { 6. File workingDir = new File("."); 7. String[] lista = workingDir.list(); 8. for(int i=0; i<lista.length; i++) { 9. System.out.println(lista[i]); 10. } 11. } 12. 13. } Lista.java Lista.class Copy.java Provare a creare un equivalente del comando ls -l Copy.class FileInfo.java FileInfo.class 25 La classe System Talvolta un programma richiede l’accesso alle risorse del sistema, allo standard output, allo standard input, ecc. La piattaforma Java consente di effettuare l’accesso alle risorse del sistema attraverso l’uso della classe System. La classe System fornisce lo stream in (di tipo InputStream) associato allo standard input, lo stream out (di tipo PrintStream) associato all’output e lo stream err associato allo standard error. Inoltre contiene alcuni metodi che svolgono diversi compiti. Ad esempio il metodo currentTimeMillis() fornisce il tempo in millisecondi (a partire dal 1/1/1970), il metodo exit(int status) interrompe l’interpretazione del programma, ecc. 26 Input da tastiera Lo standard input di un computer è visto attraverso l’oggetto predefinito System.in Questo oggetto mette a disposizione un numero limitato di operazioni Esistono delle classi predefinite che a partire da questo oggetto creano nuovi oggetti con maggiori funzionalità La classe InputStreamReader Un InputStreamReader converte una sequenza di byte in una sequenza di caratteri in accordo con uno specifico sistema di codifica. La classe BufferedReader Un BufferedReader legge una sequenza di caratteri, la memorizza in un buffer in modo da fornire funzioni per la lettura di intere linee. 1. InputStreamReader reader = new InputStreamReader(System.in); 2. BufferedReader console = new BufferedReader(reader); Dopo queste operazioni posso utilizzare l’oggetto console e il metodo readLine() in grado di restituirmi una linea da tastiera (tutti i caratteri immessi fino alla pressione di un fine linea) sotto forma di stringa. String line = console.readLine(); 27