En ocaciones necesitamos almacenar el estado de un objeto dentro de un dispositivo de almacenamiento, pero el manejar el archivo y escribir cada atributo del objeto es una tarea cansada, pero java tiene una clase que nos ayuda a guardar el estado del objeto tal y como lo mantenemos en la ejecución del programa. Esta clase es conocida como Serializable.
Serialización de un objeto
La serialización de un objeto consiste en obtener una trama de bytes que represente el estado de un objeto, donde podrá ser escrito dentro de un archivo, o bien, para ser enviado a través de una red. Una característica importante es que esto hace posible la persistencia de objetos, es decir, el estado de un objeto se almacena para su uso posterior.
¿Qué es Serializable?
Serializable es una clase ubicada en el paquete Java.io.Serializable, la cual no cuenta con ningún método, por lo que es una clase que sirve solamente para especificar que todo el estado de un objeto instanciado podrá ser escrito o enviado en la red como una trama de bytes.
Hay que tomar en cuenta que, si un objeto tiene como atributo otro objeto, entonces se debe declarar ese objeto del tipo Serializable, y estos serán serializados primero. Esto se puede tomar como un árbol, donde las hojas son objetos que forman parte de otro objeto como un atributo, y todos ellos son marcados como serializables, para así entonces serializar primero las hojas del árbol y finalizar con la raíz.
Habrá ocaciones donde querramos exceptuar un atributo del objeto que no querramos serializar, y para esto se encuentra el modificador Transient. Este modificador le indica a la JVM (Java Virtual Machine) que dicho atributo deberá ser excentado de la serialización, en otras palabras, ignorará este atributo.
Los atributos que lleven el modificador Static nunca se tomarán en cuenta al serializar un objeto, ya que este atributo pertenece a la clase y no al objeto.
Ejemplos de serialización
Aquí se muestran ejemplos de cómo debemos implementar serializable dentro de una clase.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.io.*; Public class unaClase implements Serializable; De esta forma, declaramos que todos los objetos instanciados de "unaClase" serán serializados. Ahora veamos un ejemplo sencillo. Crearemos una clase llamada Agenda, la cual será serializable: 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; } } |
Notamos que el atributo s_Apellido lleva el modificador Transient, por lo que la JVM no serializará ese dato.
Ahora veamos como usaremos los objetos marcados como Serializable para lectura y escritura en archivos.
Output (Escritura)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.io.*; public class TestAgenda{ public static void main(String[] args){ Agenda a1 = new Agenda("Ana", "Martínez", "Fernández"); Agenda a2 = new Agenda("Ernesto", "García", "Pérez"); try{ FileOutputStream fs = new FileOutputStream("agenda.ser");//Creamos el archivo ObjectOutputStream os = new ObjectOutputStream(fs);//Esta clase tiene el método writeObject() que necesitamos os.writeObject(a1);//El método writeObject() serializa el objeto y lo escribe en el archivo os.writeObject(a2); os.close();//Hay que cerrar siempre el archivo }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } |
En este código podemos observar el uso de FileOutputStream y ObjectOutputStream los cuales son clases para escritura dentro de archivos. Dentro de la clase ObjectOutputStream encontramos el método WriteObject, el cual escribe el estado del objeto, como una trama de bytes, dentro del archivo.
Ahora bien, veamos cómo se lee un objeto que ya fue serializado y que se ha escrito en un archivo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
try{ FileInputStream fis = new FileInputStream("agenda.ser"); ObjectInputStream ois = new ObjectInputStream(fis); a1 = (Agenda) ois.readObject();//El método readObject() recupera el objeto a2 = (Agenda) ois.readObject(); ois.close(); fis.close(); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); }catch(ClassNotFoundException e){ e.printStackTrace(); } |
En este caso, se hace uso de las clases FileInputStream y ObjectInputStream. La clase ObjectInputStream contiene el método readObject, el cual lee una trama de bytes, que representa el estado de un objeto. Este método retorna un objeto del tipo Object, por lo que debemos convertir el objeto retornado al tipo de objeto que estamos leyendo del archivo.
En este vínculo se puede descargar la presentación: Serializable Java.
Saludos
Guardo los datos de los pacientes: numero de expediente, dni, apellidos, nombres, telefono, direccion y fotografia en un archivo binario, pero al parecer se sobreescribe el archivo, por eso cuando busco solo me muestra el ultimo ingresado, dejo aqui los codigos de guardar y buscar respectivament para que me puedan ayudar. gracias:
private void btcGuardarActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Object nombreArchivo = archivo;
System.out.println(nombreArchivo);
try{
ObjectOutputStream fileout = new ObjectOutputStream(new FileOutputStream((String) nombreArchivo));
fileout.writeObject(txtNroExpediente.getText());
fileout.writeObject(txtDni.getText());
fileout.writeObject(txtApellidos.getText());
fileout.writeObject(txtNombres.getText());
fileout.writeObject(txtDireccion.getText());
fileout.writeObject(txtTelefono.getText());
fileout.writeObject(lblFoto.getIcon());
JOptionPane.showMessageDialog(null, “Los datos del paciente se guardaron corecttamente…”);
if(fileout!=null){
fileout.close();
}
}catch(IOException e){}
}
private void btcBuscarActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Object nombreArchivo = archivo;
try{
try (ObjectInputStream filein = new ObjectInputStream(new FileInputStream((String) nombreArchivo))){
Object expediente = filein.readObject();
Object dni = filein.readObject();
Object apellidos = filein.readObject();
Object nombres = filein.readObject();
Object direccion = filein.readObject();
Object telefono = filein.readObject();
Object foto = filein.readObject();
if (txtNroExpediente.getText().equals(expediente)){
txtNroExpediente.setText((String) expediente);
txtDni.setText((String) dni);
txtApellidos.setText((String) apellidos);
txtNombres.setText((String) nombres);
txtDireccion.setText((String) direccion);
txtTelefono.setText((String) telefono);
lblFoto.setIcon((Icon) foto);
}
if(filein!=null){
filein.close();
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(JDPacientes.class.getName()).log(Level.SEVERE, null, ex);
}
}catch(IOException e){}
}
Encotre un pequeño error Serializable es una interface no una clase, muchas gracias por el artículo