Serialización en ficheiros
Sumario
Serialización en ficheiros
Qué é a serialización de obxectos? A serialización é un proceso de trasformación que nos permite codificar obxectos da nosa arquitectura orientada a obxectos. Esta codificación sírvenos para transmitir ou almacenar obxectos. No noso caso vamos a traballar nunha forma de almacenamento e recuperación de obxectos en ficheiros, pero a serialización tamén é úsada en sockets, en modelos cliente servidor etc… e decir fluxos (stream).
A necesidade de serialización xurde no propio paradigma de programación orientada a obxectos. E moito máis cómodo e natural andar a manexar obxectos, que non datos primitivos ou cadeas de alfanuméricos obtidos de ficheiros. Entón Java permitenos gardar e recuperar obxectos en ficheiros binarios.
Para a serialización de obxectos (que non é máis que escribir ou ler un obxecto completo) fai falla un obxecto serializable: unha secuencia de bytes que contén datos do propio obxecto e metadatos do mesmo. Estos metadatos son o tipo de obxecto que é e a súa arquitectura interna (datos primitivos ou referencias a outros obxectos). Para indicar a Java que un obxeto é serializable a sua clase ten que implementar a interfaz Serializable, desta forma:
Public class Agenda implements Serializable {
private String nombre;
private String p_Apellido;
private transient String s_Apellido;
…
…
public Agenda(String nombre, String p_Apellido, String s_Apellido){
this.nombre = nombre;
this.p_Apellido = p_Apellido;
this.s_Apellido = s_Apellido;
}
}
Aspectos útiles a ter en conta na serialización:
- Coa herdanza as clases fillo son tamén serializable se o son no pai.
- Todo os atributos de clase tipo primitivo son serializables.
- Se non se desexa serializar algún atributo úsase o modificador transient.
- Unha interfaz non se pode serializar.
- As colecciones de obxectos pódense serializar.
- SerialVersionUID: é un identificador de clases cando serializamos os seus obxectos. Vai ser un atributo da clase de tipo long, estático e inmutable (final):
private static final long serialVersionUID = 4L;
Para todo o proceso de serialización e deserialización temos dúas clases ObjectInputStream e ObjectOutputStream, que se expoñen a continuación.
Escritura e serialización de obxectos
Na escritura de un obxecto nun ficheiro necesitamos crear un fluxo de saída primeiro. O máis frecuente é coa clase FileOutputStream, a partires do fluxo xa podemos crear un obxecto ObjectOutputStream, que ten o método de escritura:
- void writeObject(Object o): método de escritura dun obxecto no fluxo que se lle pasa como parámetro.
Exemplo→ paquete unidad1.serializacion.CreateSequentialFile.java
Lectura e deserialización de obxectos
A lectura é moi semellante a escritura; é necesario crear un obxecto de lectura de fluxo co FileInputStream. Despois xeneramos ObjectInputStream que ten o método de lectura:
- Object readObject(): obtense un obxecto do ficheiro e deserializao, de maneira secuencial, un detrás doutro.
Exemplo→ paquete unidad1.serializacion.ReadSequentialFile.java
Problema na sobreescritura de ficheiros na serialización:
Se intentas abrir e agregar novos obxectos nun ficheiro xa utilizado, é decir agregar obxectos, o máis probable é que cando queras ler che apareza o seguinte erro: Error → IOException: invalid type code: AC É provocado porque se crea unha cabeceira extra sempre que se abre o ficheiro en modo escritura. Esa cabeceira ten a información dos metadatos dos obxectos almacenados e non pode estar duplicada. Para arranxar este problema hai que programar un propio ObjectOutputStream e sobreescribir o método writeStreamHeader:
Exemplo → SobreEscrituraSer.java
Actividades
Actividade 1 - Almacenar lista de obxectos nun ficheiro
Crea un programa que almacene nunha lista obxectos Employee e se almace nun ficheiro. Logo debes recuperar esa lista de obxecto do ficheiro. Solución: unidad1.actividadeSer
Actividade 2
De Ferrol yo tengo una parecida pero mezcla más cosas: https://wiki.cifprodolfoucha.es/index.php?title=Prog._Ficheros#Ejercicio_propuesto:_Aplicando_el_polimorfismo