Input/Output Planning & Scheduling Team ISTC-CNR Input/Output • I programmi Java eseguono l’I/O mediante i flussi. • Un flusso (stream) è una astrazione che produce e/o consuma informazioni. • Ogni flusso è collegato ad un dispositivo fisico dal sistema di I/O di java. • Tutti i flussi si comportano allo stesso modo, a prescindere dal dispositivo fisico al quale sono collegati → le stesse classi e gli stessi metodi di I/O possono essere applicati a qualunque tipo di dispositivo (console, file, connessione di rete,…). • Il java implementa i flussi all’interno di una gerarchia di classi definite nel pacchetto java.io; Planning & Scheduling Team ISTC-CNR 1 Input/Output java.io classe InputStream • • classe OutputStream Java ha diverse sottoclassi concrete per gestire le differenze tra i diversi dispositivi. Per utilizzare le classi definite in java.io occorre importare tale pacchetto nel proprio programma tramite l’istruzione: import java.io.*; • Le classi InputStream e OutputStream definiscono diversi metodi che le altre classi implementano: – – il metodo read() il metodo write() Planning & Scheduling Team ISTC-CNR Input/Output • Noi abbiamo sempre utilizzato alcuni flussi, finora senza saperlo, ad esempio: – – System.out System.in Flusso standard di output (per default indirizzato alla console) Flusso standard di input (per default indirizzato alla tastiera) (importati automaticamente dal pacchetto java.lang) • Questi flussi possono essere reindirizzati a qualunque dispositivo di I/O compatibile. Ad esempio, il flusso di input potrebbe essere reindirizzato su un file. System.in Planning & Scheduling Team ISTC-CNR 2 Input/Output import java.io.*; class UseRead { public static void main(String args[]) throws IOException { char c; System.out.println("Fornire i caratteri, 'q' per terminare."); do { c = (char) System.in.read(); System.out.println(c); } while(c!='q'); } } • Il metodo read() legge un singolo byte dal flusso di input (la tastiera) e lo restituisce come valore intero, restituendo -1 quando viene raggiunta la fine del flusso. • Notate: l’input non viene passato al programma fino a che l’utente non preme INVIO: il metodo read() non è molto adatto per l’input interattivo da console! Planning & Scheduling Team ISTC-CNR Input/Output 1. 2. 1. Lettura di una stringa - abbiamo due opzioni: utilizzare il metodo read() per leggere i caratteri in un array di bytes e poi convertire l’array in un oggetto String; utilizzare il metodo readLine() messo a disposizione dal java. E’ molto più comodo in quanto legge direttamente una sequenza di caratteri dal flusso di input e li restituisce in un oggetto di tipo String; Passi da compiere: istanziare un oggetto DataInputStream [costruttore: DataInputStream(InputStream flussoInput)] Il metodo readLine() sarà mandato in esecuzione dall’oggetto appena istanziato sul flusso di input passatogli per parametro: DataInputStream inData = new DataInputStream(System.in); inData.readLine(); Planning & Scheduling Team ISTC-CNR 3 Input/Output L’esempio completo: import java.io.*; class ReadLines { public static void main(String args[]) throws IOException { DataInputStream inData = new DataInputStream(System.in); String str; System.out.println("Fornire una riga di testo."); System.out.println("Fornire 'stop' per terminare."); do { str = inData.readLine(); System.out.println(str); } while(!str.equals("stop")); } } Planning & Scheduling Team ISTC-CNR Input/Output • • Scrittura dell’output della console utilizzare i metod1 print() e println() definiti dalla classe PrintStream. (Quindi PrintStream è il tipo di oggetto a cui fa riferimento System.out) La classe PrintStream deriva da OutputStream: ne consegue che è possibile scrivere nella console utilizzando il metodo write(): import java.io.*; class WriteDemo { public static void main(String args[]) throws IOException { int b; b = 'A'; System.out.write(b); System.out.write('\n'); } } Planning & Scheduling Team ISTC-CNR 4 Input/Output • • Lettura e scrittura dei file le classi FileInputStream e FileOutputStream creano flussi collegati ai file. per aprire un file, basta istanziare un oggetto su una di queste classi, specificando il nome del file come argomento per il costruttore FileInputStream(String nomeFile) throws FileNotFoundException FileOutputStream(String nomeFile) throws IOException • • • per leggere da un file è possibile utilizzare una versione del metodo read() definita all’interno di FileInputStream per scrivere in un file è necessario utilizzare il metodo write() definito da FileOutputStream al termine dell’esecuzione occorre chiudere il file utilizzando il metodo close() Planning & Scheduling Team ISTC-CNR Input/Output import java.io.*; class ShowFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; try { fin = new FileInputStream(args[0]); } catch(FileNotFoundException e) { System.out.println("File Not Found"); return; } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Usage: ShowFile File"); return; } do { i = fin.read(); if(i!=-1) System.out.print((char) i); } while(i != -1); fin.close(); } } Planning & Scheduling Team ISTC-CNR 5 Input/Output import java.io.*; class CopyFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; FileOutputStream fout; try { fin = new FileInputStream(args[0]); fout = new FileOutputStream(args[1]); } catch(FileNotFoundException e) { System.out.println("File Not Found"); return; } catch(IOException e) { System.out.println("Error opening output File"); return; } //CONTINUA… Planning & Scheduling Team ISTC-CNR Input/Output //CONTINUA… catch(ArrayIndexOutOfBoundsException e) { System.out.println("Usage: CopyFile From To"); return; } try { do { i = fin.read(); if(i!=-1) fout.write(i); } while(i != -1); } catch(IOException e) { System.out.println("File Error"); } fin.close(); fout.close(); } } Planning & Scheduling Team ISTC-CNR 6