NOTA! Questo sito utilizza i cookie e tecnologie simili.

Se non si modificano le impostazioni del browser, l'utente accetta. Per saperne di piu'

Approvo

JAVA, i/o su file e persistenza dei dati: le BASI della serializzazione degli oggetti e loro lettura e scrittura da e su file.

 

L'argomento di questo articolo sembrerebbe avere poco a che fare con la Computer Grafica.


In realtà, la persistenza dei dati è un argomento trasversale, che riguarda più o meno tutti i campi dell'informatica; questo sito, inoltre, non vuole limitarsi alla “sola” cg, ma occuparsi anche – lo si è visto con una lunga serie di videotutorial – di sviluppo di videogiochi e altri campi.

Esistono diverse classi e vari metodi per scrivere, via Java, su File. E' possibile scrivere stringhe di testo (ASCII) o OGGETTI, attraverso un meccanismo che si chiama SERIALIZZAZIONE. Parlerò di questo secondo metodo.

 


La serializzazione dei dati consiste nel trasformare gli oggetti – nel senso informatico del termine (quindi anche stringhe, ma considerandole come entità, non prendendone solo il testo ASCII) e con la possibilità di trattare oggetti decisamente più complessi - in stream di byte. Il procedimento inverso è detto deserializzazione.

 

Faccio notare che la serializzazione riguarda solo il passaggio appena descritto: la scrittura su file è solo una delle applicazioni pratiche che è possibile svolgere trattando stream di byte, ed è quella che mostrerò.

Il cuore di tutto sta nell'interfaccia Serializable e in due classi: ObjectOutputStream e ObjectInputStream. Per usare queste componenti è necessario importare il package java.io .

Vediamo subito un po' di codice: quali istruzioni sono necessarie per prendere un oggetto e scriverlo su file? Eccole:



import java.io.*;
class scritturaSuFile
{
public static void main(String[] args)
{
StringBuffer mioSB = new StringBuffer(“Stringa di prova”);

try // Sempre necessario quando si ha a che fare con i/o su file
{
// Prima creo il “destinatario”: uno stream di scrittura su file
FileOutputStream fos = new FileOutputStream(“PathFileSuCuiScrivere.dat”);
// NOTA: l'estensione è del tutto arbitraria... Ovviamente, evitate di scegliere estensioni quali .exe o .bat :-)
// Ora posso scrivere l'oggetto sotto forma di stream di byte e passarlo al file
ObjectOutputStream oos = new ObjectOutputStream(fos);
// Trasformazione dei dati in stream di byte
oos.write(mioSB);
oos.close()
}
catch(Exeption e)
{
System.out.println(“Eccezione: “ + e.toString());
}
}
}



Per curiosità, fate varie prove con varie stringhe e con vari oggetti, ed aprite il file dei dati scritto di volta in volta con un editor di testo, per vedere “cosa ha salvato”, effetttivamente, Java.

 


Vediamo ora come fare il “ritorno”, ossia: dato un file contenente dei dati serializzati, leggerli e trasformarli in oggetti “comprensibili” dal programma (nel nostro caso, stamperemo a video la stringa letta dal file).



import java.io.*;
public class letturaDaFile
{
public static void main(String[] args)
{
StringBuffer mioSB = null; // Il “destinatario” dell'informazione letta
try
{
// Recupero il file dei dati e creo un ObjectInputStream per leggerlo
FileInputStream fis = new FileInputStream(“PathDelFileDiInput.dat”);
ObjectInputStream ois = new ObjectInputStream(fis);
mioSB = (StringBuffer) ois.readObject(); // Notate il cast !!!
ois.close();
}
catch(Exeption e)
{
System.out.println(“Eccezione: “ + e.toString());
}
}
}


I tipi di base (boolean, byte, Character, Class, Double, Float, Integer, Long, Number, ...) sono serializzabili in maniera nativa; altri, come Object, no.


E' possibile comunque creare tipi serializzabili: devono implementare l'interfaccia Serializable.
Tale interfaccia non contiene campi o metodi: “dice” semplicemente che gli oggetti creati con la classe che li implementa sono serializzabili.

Classi che necessitino di operazioni particolari per la gestione della serializzazione e della deserializzazione devono implementare i seguenti metodi (con queste firme precise):


private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;


Osservazione: quando si tenta di “scrivere” (o leggere) un grafo, alcuni oggetti potrebbero non implementare l'interfaccia Serializable; in quel caso, verrà lanciata l'eccezione NotSerializableException, che permetterà, tra l'altro, di identificare la classe dell'oggetto che non può essere serializzato.

E' facile intuire, da quanto detto, quanto possa essere utile e pratico creare un modulo per la serializzazione dei dati all'interno del proprio programma. E' addirittura facile, se vogliamo!


NOTA IMPORTANTE: ovviamente, i “contro” ci sono, e tra questi ce n'è uno importante... Modificando una classe che fa uso di metodi per leggere e scrivere dati serializzati, sarà impossibile leggere i dati scritti con versioni precedenti della stessa.


Per ovviare a questo problema non c'è una vera e propria soluzione, quanto più che altro degli accorgimenti e delle “pezze”... ma magari tratteremo questo e altri problemi della serializzazione dei dati in un'altra puntata.

 

 
Vai all'inizio della pagina