Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Serializzazione e Deserializzazione di Oggetti in Java: Guida Dettagliata - Prof. Coen Por, Appunti di Elementi di Informatica

Una guida dettagliata sulla serializzazione e deserializzazione di oggetti in java. Esplora le interfacce objectinput e objectoutput, i metodi per la scrittura e la lettura di oggetti, e le classi objectoutputstream e objectinputstream. Include esempi di codice per illustrare come serializzare e deserializzare tipi base e oggetti complessi, affrontando anche la gestione della sicurezza nella serializzazione con la codifica degli attributi. Utile per studenti e sviluppatori che desiderano approfondire la gestione degli oggetti in java.

Tipologia: Appunti

2024/2025

In vendita dal 15/11/2025

AriBab
AriBab 🇮🇹

88 documenti

1 / 14

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Programmazione concorrente e distribuita
27/03/2025
La serializzazione
La serializzazione è un operazione mediante la quale è possibile scrivere su uno stream i valori
contenuti all'interno di un oggetto.
L'operazione inversa è detta de-serializzazione.
La serializzazione consente di:
Trasferire le informazioni di un oggeto, se lo stream è associato a unc anale di
comunicazione;
Salvare permanentemente le informazioni di un oggetto, se lo stream è associato ad un
file;
Oggetto identifici Oggetto
Serializzazione Byte Stream Deserializzazione
Le operazioni di scrittura e lettura che avvengono mediante degli stream di oggeti sono definite
tramite le interfacce:
ObjectOutput, per la scrittura;
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Anteprima parziale del testo

Scarica Serializzazione e Deserializzazione di Oggetti in Java: Guida Dettagliata - Prof. Coen Por e più Appunti in PDF di Elementi di Informatica solo su Docsity!

Programmazione concorrente e distribuita

La serializzazione

La serializzazione è un operazione mediante la quale è possibile scrivere su uno stream i valori

contenuti all'interno di un oggetto.

L'operazione inversa è detta de-serializzazione.

La serializzazione consente di:

  • Trasferire le informazioni di un oggeto, se lo stream è associato a unc anale di

comunicazione;

  • Salvare permanentemente le informazioni di un oggetto, se lo stream è associato ad un

file;

Oggetto identifici Oggetto

Serializzazione Byte Stream Deserializzazione

Le operazioni di scrittura e lettura che avvengono mediante degli stream di oggeti sono definite

tramite le interfacce:

  • ObjectOutput , per la scrittura;
  • ObjectInput , per la lettura; ObjectOutput
  • void close (): Chiude lo stream;
  • void flush (): Flush dello stream;
  • void writeObject (Object obj): Scrive un oggetto sullo stream sottostante; ObjectInput
  • int available (): Ritorna il numero di byte che vengono letti;
  • void close (): Chiude l'input stream;
  • Object readObject (): Legge un oggetto dallo stream sottostante e lo restituisce (restituisce

un generico oggetto starà al programmatore capire di che tipo sarà);

La serializzazione

Le interfacce sono implementate dalle classi:

  • ObjectoutputStream , per la scrittura;
  • ObjectInputStream , per la lettura ObjectoutputStream

Implementa i metodi dell'interfaccia ObjectStream:

void writeObject(object obj) throw IOException

La serializzazione dei tipi base di java avviene facendo uso dei metodi messi a disposizione del

linguaggio:

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

La deserializzazione dei tipi base di java avviene facendo in modo altrettando semplice:

public class Esempio { public static void main(String[] args) throws IOException { String fileName = "tmp.bin"; ObjectInputStream is = new ObjectInputStream( new FileInputStream(fileName)); int letto = newis.readInt(); System.out.println("Letto: " + letto); is.close(); } } La serializzazione

Un oggetto per essere serializzato deve essere istanza di una classe che:

  • Implementa l'interfaccia Serializable definita nel package java.io;
  • Possiede l'attributo statico:

private static final long serialVersionUID =...

◦ Usato per verificare che le classi usare per serializzare e deserializzare siano compatibili;

◦ Se non definito vien calcolato in modo utonomo da JVM;

Durante la serializzazine vengono scritti i valori di tutti gli attributi, più le altre informazioni che

servono per ricostruire gli oggett al momento della deserializzazione.

Nota bene

Se gli attributi sono dei riferimenti ad altri oggetti, la serializzazione procede in maniera

ricorsiva.

  • Tutti gli oggetti che si incontrano devono essere oggetti serializzati.

Tutti i tipi base sono per definizione serializabili. Un oggetto è detto serializabile se la sua classe

o la sua superclassse implementano l'interfaccia Serializable.

Nota bene

  • Gli attributi stati non vengono serializzati.
  • Gli attributi con modificatore transient non vengono serializzati

Se un oggetto serializzabile ha un riferimento a un oggetto non serializzabile, il codice verrà

  • Un'istanza di A
  • Un'istanza di B;

Effettua la serializzazione in un file passato come parametro

class creaSerializza { public static void main(String[] args) throws IOException { A a1 = new A(1, "prova"); B b1 = new B(200,a1); if (args.length != 1 ) { System.err.println("Uso: creaSerializza "); System.exit(-1); } File f = new File(args[0]); if (f.exists()) f.delete(); f.createNewFile(); ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(f)); out.writeObject(b1); out.close(); } }

programma che ricorstruisce la struttura, serializzata in precedenza, da un file passato come

parametro, e stampa il valoer degli attributi

class deserializza { public static void main(String[] args) throws IOException { if (args.length != 1 ) { System.err.println("Uso: deserializza "); System.exit(-1); } File f = new File(args[0]);

if (!f.exists()) { System.err.println("File " + args[0] + " inesistente"); System.exit(-1); } ObjectInputStream in = new ObjectInputStream( new FileInputStream(f)); try { B ref = (B) in.readObject(); System.out.println("A.val = " + ref.getA().getVal()); System.out.println("A.txt = " + ref.getA().getTxt()); System.out.println("B.val = " + ref.getVal()); in.close(); } catch (ClassNotFoundException e) { System.err.println("Errore di deserializzazione"); e.printStackTrace(); I in.close(); System.exit(-1); } } } Stream di oggetti e Socket

Il passaggio di dati attraverso un socket può avvenire utilizzando degli stream di oggetti

costruiti sui ByteStream assocaiti al socket.

  • Gli oggetti devono essere istanza di classi che implementano l'interfaccia Serializable.

Attraverso l'implementazione dell'interfaccia Serializable una classe diventa serializzabile.

Tuttavia, nessuna implementazione viene richiesta al programamtore

  • Implementazione "fantasma";

Il comportamento ottenuto è quello descritto precedentemente (serializzazione standard).

class B implements Serializable { private static final long serialVersionUID = 1L; private int val; private A Aref; public B(int i, A ref) { val = i; Aref = ref; } public int getVal() {return val;} public A getA() {return Aref;} }

Vogliamo creare una sottoclasse di A in grado di codificare i valori degli attributi al momento

della serializzazione, utilizzando una chiave.

Il valore intero verrà codificato sommandogli l'hashCode associato alla chiave (CodificaVal() ).

La stringa verrà codificata "sommando a ogni carattere il carattere in analoga posizione nella

chaive:

  • Se la stringa è più lunga della chiave, si concatena la chiave tante volte quanto necessario;
  • Metodo codificaTxt

La classe Asicura:

  • Estende la classe A;
  • Aggiunge un attributo key: la chiave da usare per la codifica;
  • Aggiunge i metodi:

◦ private int codificaVal();

◦ private String codificaTxt();

per ottenere i valori codificati degli attributi Val e txt usando la key;

  • Aggiunge il metodo:

◦ public void decode(String p);

per decodificare gli attributi val e txt usando p come chiave.

class ASicura extends A{ private String key; public ASicura(int i, String s, String p) { super(i, s); key = p; } private int codificaVal() { return(super.val + key.hashCode()); } private String codificaTxt() { char[] newTxt = super.txt.toCharArray(); char[] keyC = key.toCharArray(); for(int i=0; i<newTxt.length; i++) newTxt[i] = (char) (newTxt[i] + keyC[i%keyC.length]); return(new String(newTxt)); } public void decode(String p) { key = p; super.val = super.val - key.hashCode(); char[] newTxt = super.txt.toCharArray(); char[] keyC = key.toCharArray(); for(int i=0; i<newTxt.length; i++) newTxt[i] = (char) (newTxt[i] - keyC[i%keyC.length]); super.txt = new String(newTxt);

  • Un'stanza di B: Serializzata entrmabe le istanze in un file passato come parametri. La classe

ASicura ha ridefinito l'operazione di serializzazione.

import java.io.*; … public class scriviSicuro { public static void main(String[] args) throws IOException { if (args.length != 2 ) { System.err.println("Uso scriviSicuro "); System.exit(-1); } A a1 = new ASicura(100, "prova a vedere se funziona", args[1]); B b1 = new B(10, a1); File f = new File(args[0]); if (f.exists()) f.delete(); f.createNewFile(); ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(f)); out.writeObject(b1); out.close(); } } Esempio / Deserializza

Programma che ricostruisce la struttura, serializzata in precedenza:

  • File passato come primo parametro;
  • DEcodifica il contenuto di ASicura usando come chiave il secondo parametro;
  • Stampa il valore deglia ttributi:

◦ Prima della decodifica;

◦ Dopo la decodifica;

import java.io.*;

public class leggiSicuro { public static void main(String[] args) throws IOException{ if (args.length != 2 ) { System.err.println("Uso: deserializza "); System.exit(-1); } File f = new File(args[0]); if (!f.exists()) { System.err.println("File " + args[0] + " inesistente"); System.exit(-1); } ObjectInputStream in = new ObjectInputStream( new FileInputStream(f)); … try { B ref = (B) in.readObject(); System.out.println("A.val = " + ref.getA().getVal()); System.out.println("A.txt = " + ref.getA().getTxt()); System.out.println("B.val = " + ref.getVal()); Asicura a = (ASicura)ref.getA(); System.out.println("Decodifico..."); a.decode(args[1]); System.out.println("A.val = " + ref.getA().getVal()); System.out.println("A.txt = " + ref.getA().getTxt()); System.out.println("B.val = " + ref.getVal()); in.close(); } catch (ClassNotFoundException e) { System.err.println("Errore di deserializzazione"); e.printStackTrace(); in.close(); System.exit(-1); } } }