File binari in Java: lettura e scrittura di byte

Dopo aver visto i file di testo (link), in quest’articolo vediamo come operare in Java con i file binari. Riprendiamo per comodità il diagramma UML con alcune classi del package java.io, del quale questa volta ci saranno utili le classi evidenziate in arancione, che ricordiamo sono quelle specializzate per la realizzazione di stream orientati al byte.

stream02

Di queste classi prenderemo in considerazione solo ciò che serve per eseguire le operazioni più comuni di scrittura e lettura di un file binario. Come al solito, per approfondimenti si rimanda alla documentazione ufficiale del linguaggio Java disponibile on line (link).

Lettura e scrittura di byte

Il modo più immediato per leggere e scrivere byte da uno stream, è utilizzare direttamente gli oggetti di classe FileInputStream e FileOutputStream attraverso i loro metodi read()write(), rispettivamente. Ad esempio, consideriamo il seguente codice di esempio:

Il codice precedente, apre il file di nome “in.dat” creando l’oggetto di nome “sorgente” di classe FileInputStream e legge un singolo byte alla volta utilizzando il metodo read() della classe FileInputStream all’interno del ciclo while. Il metodo read() della classe FileInputStream, restituisce un intero che vale -1, se raggiunge la fine del file, oppure che rappresenta il byte letto sotto forma di int. Ciascun byte letto nel ciclo, inoltre, viene passato sotto forma di int al metodo write() dell’oggetto di nome “destinazione” di classe FileOutputStream, che lo scrive nel file di nome “out.dat“.

In sostanza, il codice precedente copia un byte alla volta dal file “in.dat” nel file “out.dat“.

Si fa notare che la classe FileInputStream può lanciare un’eccezione di classe FileNotFoundException, se durante l’apertura del file (che coincide con la creazione dell’oggetto) per qualunque ragione il file non è disponibile, mentre il suo metodo read() può lanciare un’eccezione di classe IOException, se per qualunque ragione lo stream di input sul file s’interrompe.

Con la creazione dell’oggetto di classe FileOutputStream, il file da aprire in scrittura viene creato se non esiste già o, al contrario, viene semplicemente aperto. Questa classe mette a disposizione un costruttore per l’apertura del file di scrittura in append, ossia in aggiunta senza perdita dei dati già presenti: FileOutputStream(String nomeFile, boolean append), che avviene impostando a true il secondo parametro. Il metodo write() può lanciare un’eccezione di classe IOException, se per qualunque ragione lo stream di output sul file s’interrompe.

P.S. Dei metodi read() e write() visti sopra, esistono anche degli overloading che permettono di leggere e scrivere più byte alla volta, ossia blocchi di byte di una lunghezza a piacere. L’efficienza delle operazione di accesso ai file, inoltre, possono essere ancora migliorate utilizzando degli stream che impiegano dei buffer di I/O, per esempio passando attraverso le classi BufferdInputStream e BufferedOutputStream per le quali si rimanda alla documentazione ufficiale del linguaggio Java disponibile on line (link).

Un altro modo di operare con i file binari, inoltre, è quello che dà la possibilità di leggere e scrivere direttamente variabili primitive e, addirittura, oggetti. Questa modalità di accesso ad un file binario viene tratta in un altro articolo a cui si rimanda: link.