Serializzazione e deserializzazione

L’operazione di scrittura su uno stream di byte di un intero oggetto, o di un grafo di oggetti, prende il nome di serializzazione.

La deserializzazione è l’operazione inversa, che comporta la lettura da uno stream di byte di un oggetto o grafo di oggetti serializzato e la ricostruzine dell’oggetto originale (in particolare, viene ripristinato lo stato di quest’ultimo, ovvero i valori degli attributi).

Untitled

Grazie a queste due operazioni, gli oggetti (che non hanno una struttura sequenziale) possono essere salvati all’interno di file, trasferiti sulla rete tramite socket, ecc...

Serializzazione di un tipo primitivo

In Java, la scrittura di tipi primitivi su uno stream di byte avviene semplicemente usando gli appositi metodi della classe ObjectOutputStream:

import java.io.*;

public class PrimitiveSerialization {
	public static void main(String[] args) throws IOException {
		String fileName = "tmp.bin";
		try (
			ObjectOutput os = new ObjectOutputStream(new FileOutputStream(fileName))
		) {
			int i = 11;
			os.writeInt(i);
			os.flush();
		}
	}
}

I contenuti del file tmp.bin creato da questo programma, qui mostrati in esadecimale sono:

ac ed 00 05 77 04 00 00 00 0b

Oltre ai 4 byte del valore intero 11 (00 00 00 0b), sono presenti delle informazioni aggiuntive, che servono all’operazione di deserializzazione per determinare come ricostruire i valori originali dai dati serializzati.

Analogamente alla serializzazione, la deserializzazione di un tipo primitivo consiste semplicemente nell’invocazione di un apposito metodo della classe ObjectInputStream:

import java.io.*;

public class PrimitiveDeserialization {
	public static void main(String[] args) throws IOException {
		String fileName = "tmp.bin";
		try (
			ObjectInput is = new ObjectInputStream(new FileInputStream(fileName))
		) {
			int i = is.readInt();
			System.out.println("Read: " + i);
		}
	}
}

Serializzazione di un oggetto

Come altro esempio, il seguente codice serializza e deserializza un oggetto - in particolare, una stringa:

import java.io.*;

public class ObjectSerialization {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		String fileName = "tmp.bin";
		try (
			ObjectOutput os = new ObjectOutputStream(new FileOutputStream(fileName))
		) {
			os.writeObject("Oggi");
			os.flush();
		}

		try (
			ObjectInput is = new ObjectInputStream(new FileInputStream(fileName))
		) {
			String s = (String) is.readObject();
			System.out.println("Read: " + s);
		}
	}
}

Anche in questo caso il file tmp.bin contiene, prima della codifica della stringa (4f 67 67 69), alcune informazioni aggiuntive necessarie alla deserializzazione:

ac ed 00 05 74 00 04 4f 67 67 69

Serializzazine di più oggetti

E’ anche possibile serializzare più oggetti su uno stream. In tal caso, quando poi si usa readObject() per effettuare la deserializzazione, bisogna sapere in che ordin sono stati scritti i dati per convertirli ai tipi corretti (in questo esempio, prima String e poi Date).