Gestione dell I/O su File

Documenti analoghi
File e Stream In Java. Prof. Francesco Accarino IIS Sesto San Giovanni Via Leopardi 132

INPUT OUTPUT Programmazione in rete e laboratorio. Le operazioni di I/O avvengono attraverso stream (sequenze di byte)

Informatica I. Ingegneria Medica. Prof. Diego Salamon

Fondamenti di Informatica C Esercitazioni di Laboratorio / 4 Outline

Input/Output in Java

Variabili e Metodi di classe Interfacce e Package Gestione di File in Java

Creazione, eliminazione, lettura e scrittura di file di testo

Corso sul linguaggio Java

Il linguaggio Java I file sequenziali

Lettura e scrittura - Stream

Creazione, eliminazione, lettura e scrittura di file di testo

Flussi, lettori e scrittori

RETI DI CALCOLATORI Linguaggio Java: Eccezioni

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni

Laboratorio di Programmazione Lezione 2. Cristian Del Fabbro

Corso sul linguaggio Java

789:;<:' .&+/"0&12%34%5&66+,("%3787%% %"+&%88$77%9%8:$:7%% ;<'&12%8%=,+>"%3787 % % % %"+&%88$77%9%8:$:7%

Il linguaggio Java. Gli stream

Input e Output in Java

Gestione di file in Java

Il sistema I/O di Java

Unità 2 I file binari

Introduzione. Java. Streams. Streams

IL LINGUAGGIO JAVA Input, Tipi Elementari e Istruzione Condizionale

Unità A1 I file testo

RETI DI CALCOLATORI Linguaggio Java: Il Package di Input Output

Operazioni di input/output. Prof. Francesco Accarino IIS Altiero Spinelli Via Leopardi 132 Sesto San Giovanni

Riferimenti ad oggetti: Fondamenti di Informatica L-B Esercitazione n 4 Java: I/O, Costruttori e altro. Riferimenti ad oggetti: (Esempio)

Eccezioni Precisazioni e approfondimenti

Eccezioni. Comportamento di default (esempio) Propagazione delle eccezioni

Laboratorio di reti I: Java IO

L input da tastiera in Java. Dott. Ing. M. Banci, PhD

Programmazione 2. Input Output su Stream e File

domenica 9 giugno 13 Serializzazione

18 - Classi parzialmente definite: Classi Astratte e Interfacce

Algoritmi di Ricerca. Esempi di programmi Java

Lezione 18 Le classi per l'input/output nel pacchetto java.io

STRINGHE IN JAVA In Java, le stringhe non sono pezzi di memo-ria con dentro dei caratteri, come in C: sono oggetti appartenenti alla classe

Programmazione in Java e gestione della grafica. Lezione 24

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

Un flusso (stream) è una astrazione che produce e/o consuma informazioni.

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali. Esempio Animali

20 - Input/Output su File

Fondamenti di informatica T-1 (A K) Esercitazione 2: Linguaggio Java, basi e controllo del flusso

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

Gestione delle eccezioni

Cifratura simmetrica

JAVA INTRODUZIONE C++ JDK e JRE API IDE (BLUEJ) JAVA Introduzione. Versioni e IDE DIAPOSITIVA 2 ALESSANDRO URSOMANDO

ProgrammazioneJava. Davide Di Ruscio Dipartimento di Informatica Università degli Studi dell Aquila.

Uso di metodi statici. Walter Didimo

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

7. Array e Collection 8. Progetto di classi 9. Ereditarietà 10. Eccezioni 11. Stream 5. Definire metodi 6. Strutture di controllo.

Uno stream o flusso di dati o canale è un percorso di comunicazione tra la sorgente di una certa informazione e la sua destinazione.

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali

Laboratorio Reti di Calcolatori Laurea Triennale in Comunicazione Digitale. Anno Accademico 2012/2013

5 - Istruzioni condizionali

La classe java.lang.object

Esempio su strutture dati dinamiche: ArrayList

10.4. La classe File e gli attributi di directory e file

Chat. Si ha un server in ascolto sulla porta Quando un client richiede la connessione, il server risponde con: Connessione accettata.

Gestione delle Eccezioni

Laboratorio di Matematica e Informatica 1

Esercitazioni Ingegneria del So2ware 3 - Programmazione Java Excep<ons, I/O

File, flussi e pacchetto java.io

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali. Esempio Animali

Operazioni di scrittura e lettura con periferici in linguaggio Java

TIPI PRIMITIVI: LIMITI

C. Horstmann Fondamenti di programmazione e Java 2 3^ edizione Apogeo

Pila di interi. Car 1. Car n. Pila di interi: Pila di Oggetti: Gli elementi che sono inseriti e tolti dalla pila sono numeri interi

Corso di Reti di Calcolatori L-A

Java Le stringhe. Stringhe

Prof. D. Malerba Dr. A. Appice - Dr. M.Ceci. Il sistema Input/Output di Java

Programmazione. Cognome... Nome... Matricola... Prova scritta del 11 luglio 2014

18 - Vettori. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Java, Oggetti e Strutture Dati di G. Callegarin - Edizioni CEDAM

Programmazione. Cognome... Nome... Matricola... Prova scritta del 22 settembre Negli esercizi proposti si utilizzano le seguenti classi:

(VHUFLWD]LRQLGLEDVHVXOOH6RFNHWLQ-DYD 6RFNHWGLWLSRVWUHDP

Esercitazione 6. Tutor: Ing. Diego Rughetti. Anno Accademico 2007/2008

Proprietà delle Classi e degli Oggetti in Java

Algebra di Boole: Concetti di base. E un algebra basata su tre operazioni logiche

14 - Metodi e Costruttori

Prova d Esame Compito A

Le basi del linguaggio Java

Errata Corrige di Manuale di Java 8

Esercitazione OBIETTIVI DELL ESERCITAZIONE

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE

Altri modi per leggere dati in ingresso

Sviluppo Applicazioni Mobile Lezione 13. Dr. Paolo Casoto, Ph.D

Gestione di files Motivazioni

Introduzione a Java. Riferimenti

Programmazione Orientata agli Oggetti in Linguaggio Java

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Programmazione a Oggetti e JAVA. Prof. B.Buttarazzi A.A. 2012/2013

Primi passi col linguaggio C

In un file di testo galera.txt sono memorizzati i dati relativi ad alcune condanne penali, ognuna con i dati:

La gestione di file e flussi in Java: note introduttive

Gestione delle eccezioni Individuazione e ripristino parseint Individuazione e ripristino Individuazione e ripristino parseint

Laboratorio Progettazione Web Le funzioni in PHP. Angelica Lo Duca IIT-CNR 2012/2013

10. File e loro attributi

Laboratorio di Informatica Lezione 4

Transcript:

Fondamenti di Informatica Prof. Alfredo Cuzzocrea University of Trieste Gestione dell I/O su File Credits to: Prof. L. Badia UniPD

Lettura da e scrittura su file Java fornisce operazioni di input/output tramite le classi del package java.io. La struttura è indipendente dalla piattaforma. Le operazioni si basano sul concetto di flusso. Un flusso (stream) è una sequenza ordinata di dati che ha una sorgente e una destinazione. L ordine della sequenza è importante: possiamo pensare a un nastro che viene inciso o riprodotto in un ordine prefissato, un dato dopo l altro.

Lettura da e scrittura su file Per prelevare dati da una sorgente bisogna collegarla a uno stream, dove leggere le informazioni in modo ordinato. Analogamente, per scrivere dati su una destinazione, bisogna collegarla a uno stream in cui inserire i dati in modo sequenziale. Già visto per lettura da input / scrittura a video. All inizio di queste operazioni occorre aprire lo stream e alla fine occorre chiuderlo.

Lettura da e scrittura su file L uso degli stream maschera la specifica natura fisica di una sorgente o una destinazione. Si possono trattare oggetti differenti allo stesso modo, ma anche oggetti simili in modi differenti. In particolare, esistono due modi principali: modalità testo (per esempio, per file di testo o per l output a console video): immediato per l utente modalità binaria (per dati elaborati): si leggono e scrivono byte, risultati non immediati per l utente

Lettura da e scrittura su file In modalità testo i dati manipolati sono in forme simili al tipo char di Java. Le classi coinvolte terminano in -Reader, -Writer In modalità binaria i dati manipolati sono byte. Le tipiche classi coinvolte si chiamano gestori di flussi e hanno il suffisso (Input/Output)Stream Per entrambi i casi abbiamo già visto le applicazioni al caso di lettura e scrittura a video (con conversioni da byte a stringhe)

Il file system Il tipo File può contenere un riferimento a un file fisico del sistema. Il riferimento è creato da un costruttore con un parametro stringa. in realtà può anche essere una directory File x = new File( temp.tmp ); associa il file temp.tmp all oggetto File di nome x. La classe dispone di utili metodi boolean: exists(), canread(), canwrite(), isfile(), isdirectory()

Il file system La classe File ha poi altri metodi utili, come: length(): ritorna il valore in byte list(): se invocato su una cartella, ritorna i nomi dei file in un array di stringhe setreadable(), setwritable(), setreadonly(): imposta diritti di lettura/scrittura createnewfile(), mkdir(): crea file/cartella delete(): cancella file/cartella getparent(): ritorna la cartella madre (./..) E alcuni campi statici, tra cui File.separator: il separatore di path (in Linux è / ).

Il file system Stampa i nomi dei file di x e delle sottocartelle: public static void stamparicors (File x) { if ( x == null!x.exists() ) { return; else if ( x.isdirectory() ) { String[] elenco = x.list(); String percorso = x.getabsolutepath(); for (String nome: elenco) { nome = percorso + File.separator + nome; stamparicors(new File(nome)); else if ( x.isfile() ) { System.out.println(x.getName());

Incapsulamento dei flussi In molti casi, i dati che leggiamo o scriviamo vanno opportunamente processati. Cifratura, compressione, conversione,... Questa operazione dovrebbe essere trasparente, per garantire portabilità: si parla in tal caso di incapsulamento dei flussi. Il package java.io mette a disposizione le classi FilterReader, FilterWriter, FilterInputStream, FilterOutputStream per incapsulare flussi.

Incapsulamento dei flussi A b W 3 flusso A b W 3 A b W 3 xy(..) flusso AD be WZ 36 flusso incapsulato

Incapsulamento dei flussi Le classi Filter- non fanno niente! Per default prendono uno stream (passato come parametro al loro costruttore) e gli girano i dati senza fare modifiche. Vanno estese a sottoclassi che fanno qualcosa. Ad esempio ZipInputStream e ZipOutputStream (del package java.util.zip) estendono Filter(Input/Output)Stream e leggono file ZIP PushbackReader estende FilterReader e reimmette i caratteri letti nel flusso (pushback). Casi particolari di incapsulamento sono poi dati dalle classi: PrintWriter, BufferedReader

Lettura/Scrittura verso file di testo Per gestire testi, Java fornisce due gerarchie, in lettura (Reader) e in scrittura (Writer). Reader e Writer sono due classi astratte che servono a definire i metodi di base per lettura e scrittura da file. Sono compresi: flush()/close(): scarica/scarica+chiude flusso read()/write(): leggi/scrivi pacchetti di char L implementazione specifica di questi metodi dipende dall estensione che si usa.

Gerarchia di Reader StringReader CharArrayReader FileReader PushbackReader InputStreamReader FilterReader <<abstract>> Reader PipedReader BufferedStreamReader LineNumberedReader

Gerarchia di Writer StringWriter CharArrayWriter FileWriter OutputStreamWriter FilterWriter <<abstract>> Writer PipedWriter BufferedWriter

Scrittura su file di testo Per aprire un file di testo, tipicamente si crea un oggetto di tipo FileWriter. La classe FileWriter ha due costruttori con un parametro: un oggetto di tipo File o anche una stringa (il nome del file su cui scrivere). A sua volta, FileWriter è incapsulato in un oggetto di tipo PrintWriter. Quindi: si scrive su questo PrintWriter w = new PrintWriter( new FileWriter( a.dat ) );

Scrittura su file di testo La classe PrintWriter è contenuta nel package java.io e serve a fornire gli stessi metodi della classe PrintStream (visti ad esempio per la sua istanza System.out). Solo, invece di stampare testo a video, lo scrivono sul file associato. Quindi si possono utilizzare i metodi print() e println() di PrintWriter per scrivere caratteri in un file aperto con successo.

Il metodo printf print e println sono metodi versatili: sono in grado di stampare tipi diversi di dato. PrintWriter (e PrintStream) hanno anche un metodo di stampa formattata: printf. Numero variabile di argomenti: sempre almeno uno, di tipo stringa, e i successivi opzionali per sostituire le parti % della stringa. Notare che i metodi di PrintWriter non sollevano eccezioni. Esiste un metodo d istanza checkerror().

Esempio di scrittura file di testo public static void stampacostanti() { f = new File( costanti.txt ); if ( f.exists() ) { System.out.println( costanti.txt esiste! ); return; String[] nomi = { Pi greco, Nepero ; double[] valori = { Math.PI, Math.E ; FileWriter fw = new FileWriter(f); PrintWriter pw = new PrintWriter(fw); for ( int i = 0; i<nomi.length; i++) { pw.printf( %s è:%10.6f,nomi[i],valori[i]); close(f);

Lettura da file di testo Analogamente alla scrittura, per leggere da file si creerà invece un oggetto FileReader. Anche in questo caso il costruttore può ricevere un parametro File o stringa. Tuttavia, un FileReader dovrebbe leggere un carattere alla volta, quindi di solito viene incapsulato in un oggetto BufferedReader: si legge da questo BufferedReader r = new BufferedReader(new FileReader( a.dat ));

Lettura da file di testo Da notare che FileReader è una sottoclasse di InputStreamReader: per incapsularlo dentro un BufferedReader la procedura è identica a quanto visto per il System.in. Se il file è in formato testo, ma si vogliono leggere in modo più efficiente i dati contenuti, si può anche pensare di usare uno Scanner. Lo Scanner si può creare da qualunque oggetto che implementa l interfaccia Readable, quindi anche direttamente da un File.

Esempio di lettura file di testo public static void stampailfile() { f = new File( a.txt ); if (!f.exists() ) { System.out.println( a.txt non esiste! ); return; FileReader fr = new FileReader(f); BufferedReader re = new BufferedReader(fr); String linea = re.readline(); while (linea!= null) { System.out.println(linea); linea = re.readline(); close(f);

Eccezioni La lettura/scrittura su file deve prevedere la possibilità che l azione non vada a buon fine. File errato, non trovato, disco pieno, con errori... Sono pertanto previste opportune eccezioni Esiste un albero di ereditarietà che parte da IOException, sottoclasse diretta di Exception: quindi è un eccezione controllata. Per errori molto gravi, esiste anche IOError (estensione di Throwable, non controllata).

Eccezioni Esempi di sottoclassi di IOException : FileNotFoundException (non c è il file) EOFException (si legge dopo la fine file)... Controllate: vanno annunciate con throws. Oppure ancora meglio ogni operazione di (lettura da scrittura verso) file può essere racchiusa dentro opportune try..catch. Vediamo un esempio: leggiamo numeri interi da valori.txt e ne stampiamo la somma su somma.txt: varie cose possono andare male.

Esempio di filtro file di testo import java.io.*; public class Prova { public static void main(string[] args) throws IOException { try { BufferedReader in = new BufferedReader(new FileReader( valori.txt )); String linea = in.readline(); int somma = 0; while (linea!= null) { somma += Integer.parseInt(linea); linea = in.readline(); in.close(); catch(numberformatexception e) { System.err.println( Errore formato, linea +linea); System.out.println( Il file è valido. );

Esempio di filtro file di testo import java.io.*; public class Prova { public static void main(string[] args) throws IOException { try { BufferedReader in = new BufferedReader(new FileReader( valori.txt )); String linea = in.readline(); int somma = 0; while (linea!= null) {... in.close(); catch(numberformatexception e) {... catch(filenotfoundexception e) { System.err.println( Manca il file valori.txt ); catch(ioexception e) { System.err.println(e); throws( new IOError() ); System.out.println( Il file è valido. );

Esempio di filtro file di testo import java.io.*; public class Prova { public static void main(string[] args) { try { BufferedReader in =... in.close(); catch(numberformatexception e) {... catch(filenotfoundexception e) {... catch(ioexception e) {... try { PrintWriter out = new PrintWriter(new FileWriter( somma.txt )); out.println( La somma è +somma); out.close(); catch(ioexception e) { System.err.println( Errore in scrittura: +e);

Chiudere il flusso In realtà la soluzione prospettata nell esempio ancora non va del tutto bene. Il flusso va sempre chiuso: lasciarlo aperto provoca errori di sincronismo sul file system, e potenzialmente mancata scrittura/lettura di dati Però la chiusura dei flussi non va messa dentro la try, o in caso di eccezioni il flusso rimarrà aperto. Soluzione perfetta: usare la clausola finally

Esempio di filtro file di testo import java.io.*; public class Prova { public static void main(string[] args) { try { BufferedReader in =... in.close(); catch(numberformatexception e) {... catch(filenotfoundexception e) {... catch(ioexception e) {... finally { in.close(); try { PrintWriter out =... out.close(); catch(ioexception e) {... finally { in.close();

Scrittura file in modalità append Di default il contenuto di un file viene sovrascritto. Se invece volessimo inserire nuovi caratteri in fondo a un file preesistente esistono ulteriori costruttori: FileWriter(File, boolean) FileWriter(String, boolean) che chiedono se vogliamo fare un append (in tal caso la variabile boolean = true). Attenzione a controllare le ulteriori eccezioni!

Lettura/Scrittura verso file binari Supponiamo di voler salvare dati per accederli in seguito (persistenza): l unica soluzione fin qua disponibile è convertire in testo. Scomodo, e in certi casi impossibile per i tipi riferimento che contengono riferimenti incrociati. Java in realtà mette a disposizione anche scrittura/lettura in formato binario. Analogo al formato testo, problemi compresi! Vale per qualunque oggetto serializzabile.

Lettura/Scrittura verso file binari Come per Reader/Writer ci sono gerarchie di ereditarietà analoghe per il formato binario. Grossomodo uguali con Reader e Writer sostituiti da InputStream e OutputStream Alla base: InputStream e OutputStream, due classi astratte che danno i metodi di base per lettura e scrittura da file. Ci sono sempre flush()/close() e anche read()/write(); questi ultimi però leggono e scrivono byte (il meno significativo di un int)

Gerarchia di -Stream In realtà le sottoclassi di InputStream e OutputStream implementano in modo specifico questi metodi astratti In particolare, si possono associare flussi a file usando File(Input/Output)Stream; hanno i soliti costruttori (una stringa o un File, e si può mettere un boolean per dire se si fa append) I file ottenuti in questo modo non saranno direttamente leggibili con un editor di testo!

Salvare dati primitivi Una volta creato il file, si possono salvare ad esempio dati di tipi primitivi se incapsuliamo il file dentro un DataOutputStream. Questa classe estende FilterOutputStream (che è sottoclasse di OutputStream) perciò è un vero e proprio incapsulamento. Accanto a write() che scrive byte ci sono writeint(), writedouble()... (ogni tipo primitivo) Per salvare numeri reali writedouble() dà maggiore precisione di una conversione a testo.

Caricare dati primitivi Allo stesso modo si possono leggere dati usando un DataInputStream, sottoclasse di FilterInputStream, che incapsula il flusso. Possiamo usare readint(), readdouble()... Il problema però è che i dati sono stati salvati come byte: è quindi importante ricordarsi l ordine in cui li leggiamo! Non c è alternativa migliore: leggere i dati in ordine sbagliato è lecito (anche se errato).

File ad accesso casuale Un alternativa all accesso come flusso di byte in sequenza è dato dall accesso casuale. In questa versione l accesso è scandito da un cursore e può andare in entrambe le direzioni. Inoltre gestisce anche l accesso read/write. La classe RandomAccessFile consente di vedere un file del file system in questo modo. Il costruttore ha due parametri: stringa/file e un ulteriore stringa (che può essere r, w, rw )

File ad accesso casuale I metodi della classe sono come per la classe Data(Input/Output)Stream: readint, readdouble,... per leggere writeint, writedouble,... per scrivere ma li ha entrambi! L accesso casuale è realizzato con il metodo getfilepointer che torna un long con la posizione del byte corrente e il metodo seek(pos) che sposta il cursore di pos