13.1 TRANSFIRIENDO OBJETOS

 

Bienvenidos a un nuevo bloque de programación en Java viendo nuevos conceptos y avanzando en el aprendizaje. Para todos aquellos que seguís el tutorial recomiendo también realizar los ejercicios, algunos son muy básicos pero la idea principal es que conozcáis métodos, como crearlos y su uso.  Dicho esto empiezo con este primer post dedicado a la Serialización.

Serializar consiste en convertir un objeto que podamos haber creado nosotros dentro de un programa de Java en una sucesión de bytes, ¿con qué objetivo? Con el objetivo de poder almacenar ese objeto en un medio de almacenamiento, un disco duro, un pendrive, etc., y en el futuro restaurar o recomponer ese objeto al estado en el que se encontraba cuando lo serializamos ya que serializar es convertir en bytes. En Java se utiliza la serialización para convertir el objeto que nosotros hemos convertido en bytes distribuirlo a través de la red a ordenadores remotos y en esos ordenadores remotos este objeto sea restablecido al estado en el que se encontraba cuando se serializó.

Para realizar la tarea de serialización vamos a utilizar lo siguiente:

·         Interfaz: Serializable

·         Clase: ObjectOutputStream

o   Método: writeObject()

·         Clase: ObjectInputStream

o   Método: readObject()

Vamos a ver todo esto en un ejemplo práctico vamos a convertir un objeto que podamos haber creado en nuestro programa Java en una sucesión de bytes, serializar el objeto. Una vez que lo hayamos guardado en el disco duro de nuestro ordenador lo rescataremos del disco duro utilizando la clase ObjectInputStream.

Nos creamos un nuevo proyecto al que vamos a llamar Serialización, dentro de este proyecto un paquete al que llamamos ser y una clase llamada Serializando cuyo código es el siguiente:

package ser;

 

import java.util.*;

 

import java.io.*;

 

public class Serializando {

 

      public static void main(String[] args) {

           

            Administrador jefe = new Administrador("Paco", 20000, 2022,12,10);

           

            jefe.setIncentivo(5000);

           

            Empleado[] personal = new Empleado[3];

           

            personal[0]=jefe;

           

            personal[1]=new Empleado("Rocio", 22000, 2022,10,8);

           

            personal[2]=new Empleado("Enrique", 18000, 2020,11,9);

 

      }

 

}

class Empleado {

     

      public Empleado(String n, double s, int agno, int mes, int dia) {

           

            nombre=n;

           

            sueldo=s;

           

            GregorianCalendar calendario = new GregorianCalendar(agno, mes-1, dia);

           

            fechaContrato = calendario.getTime();

           

      }

     

      public String getNombre() {

           

            return nombre;

      }

     

      public double getSueldo() {

           

            return sueldo;

      }

     

      public Date getFechaContrato() {

           

            return fechaContrato;

      }

     

      public void subirSueldo(double porcentaje) {

           

            double aumento = sueldo*porcentaje/100;

            sueldo+=aumento;

      }

     

      public String toString() {

           

            return "Nombre "+nombre+" Sueldo "+sueldo+" Fecha contrato "+fechaContrato;

      }

     

      private String nombre;

     

      private double sueldo;

     

      private Date fechaContrato;

}

 

class Administrador extends Empleado{

     

      public Administrador(String n, double s, int agno, int mes, int dia) {

           

            super(n, s, agno, mes, dia);

           

            incentivo=0;

      }

     

      public double getSueldo() {

           

            double sueldoBase=super.getSueldo();

           

            return sueldoBase + incentivo;

      }

     

      public void setIncentivo(double b) {

           

            incentivo=b;

      }

     

      public String toString() {

           

            return super.toString()+" Incentivo "+incentivo;

      }

     

      private double incentivo;

}

 

En este ejemplo además del método principal main tenemos dos clases, la clase Empleado con su constructor que recibe varios parámetros, esta clase lo que hace es construir objetos de tipo Empleado y estos objetos van a tener un nombre, un sueldo y una fecha de alta en el contrato.

Luego están los métodos Getter para poder leer el nombre del empleado, el sueldo y la fecha de alta en el contrato.

Esta clase también tiene un método subirSueldo para aumentar el sueldo a un empleado.

También tenemos el método toString pertenece a la clase Object se utiliza para especificar una descripción de nuestra clase es como verbalizar lo que hace nuestra clase o pasar a texto lo que hace la clase.  Y luego están las variables de clase.

La segunda clase Administrador hereda de la clase Empleado con su constructor, también cuenta con una serie de métodos para añadir un incentivo y para especificar una descripción de la clase.

En la clase principal creamos un objeto de tipo Administrador denominado jefe que le hemos establecido un incentivo, hemos creado un array de tipo Empleado, en la primera posición del array hemos almacenado el objeto de tipo Administrador y en las otras dos posiciones hemos almacenado objetos de tipo Empleado.

Lo que vamos a hacer en este ejemplo es serializar este array:

Empleado[] personal = new Empleado[3];

Esto implica que lo vamos a convertir en una sucesión de bytes para almacenar este objeto Empleado personal en nuestro disco duro y después lo que haremos será rescatarlo del disco duro e imprimir el resultado en consola.

Primero hemos de fijarnos qué tipo de objeto es el que queremos serializar, es un objeto de tipo Empleado por lo que tenemos que ir a la clase Empleado y que implemente la interfaz Serializable:

class Empleado implements Serializable{

Con esto le estamos indicando que los objetos que pertenezcan a esta clase se pueden convertir en bytes.

El siguiente paso es construir un flujo de datos de tipo ObjectOutputStream dentro del método main, esta clase lanza un error de tipo IOException por lo que hay que crearla dentro de un bloque try… catch.

try {

                 

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

            }catch(Exception e) {

 

      }

Creamos el objeto de tipo ObjectOutputStream que le llamamos escribiendo_fichero el argumento que nos pide es de tipo OutputStream por lo que instanciamos la clase FileOutPutStream al que le pasamos la ruta donde nos va a crear el texto.

Ahora lo que tenemos que hace es escribir este objeto, el objeto que queremos que viaje al exterior es el array personal por lo que hacemos lo siguiente:

            try {

                 

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

Y cerramos el flujo de datos:

            try {

                 

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

                 

                  escribiendo_fichero.close();

El archivo nos lo va a crear en una carpeta que se llama serializacion que está en el Escritorio.

Con esto ya estaría terminado, si lo ejecutamos el programa parece que no hace nada pero si vamos a la carpeta nos ha creado el archivo empleado:



Ahora vamos a ver como rescatar el objeto volvemos dentro de la cláusula try después de haber cerrado el flujo de datos nos creamos un objeto de tipo ObjectInputStream.

try {

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

                 

                  escribiendo_fichero.close();

                 

                  ObjectInputStream recuperando_fichero = new ObjectInputStream(new FileInputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

Una vez hecho esto tenemos que utilizar el método read() para leer un objeto, el objeto que estamos leyendo es un array una vez que leamos este objeto habrá que almacenarlo en algún sitio por lo que tendremos que almacenarlo en otro array y tiene que ser de tipo Empleado por lo que creamos un array de tipo Empleado al que vamos a llamar personal_recuperado al utilizar el método readObject() lo que hace este método es leer un objeto desde ObjectInputStream y devuelve un objeto de tipo Object por lo que tendremos que hacer un casting para transformar este objeto de tipo Object a Empleado por lo que lo haríamos de la siguiente forma:

            try {

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

                 

                  escribiendo_fichero.close();

                 

                  ObjectInputStream recuperando_fichero = new ObjectInputStream(new FileInputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  Empleado[] personal_recuperado =(Empleado[]) recuperando_fichero.readObject();

                 

Cerramos el flujo de datos:

try {

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

                 

                  escribiendo_fichero.close();

                 

                  ObjectInputStream recuperando_fichero = new ObjectInputStream(new FileInputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  Empleado[] personal_recuperado =(Empleado[]) recuperando_fichero.readObject();

                 

                  recuperando_fichero.close();

Para ver la información hay que crear un bucle for que recorra el archivo:

try {

                  ObjectOutputStream escribiendo_fichero = new ObjectOutputStream(new FileOutputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  escribiendo_fichero.writeObject(personal);

                 

                  escribiendo_fichero.close();

                 

                  ObjectInputStream recuperando_fichero = new ObjectInputStream(new FileInputStream("C:/Users/usuario/Desktop/serializacion/empleado.txt"));

                 

                  Empleado[] personal_recuperado =(Empleado[]) recuperando_fichero.readObject();

                 

                  recuperando_fichero.close();

                 

                  for(Empleado e : personal_recuperado) {

                       

                        System.out.println(e);

                  }

Si probamos vemos que la información se muestra en la consola:



Con cualquier duda comentarlo a través de los comentarios del blog. Saludos!

12.6 ESCRIBIENDO ARCHIVOS COMO BYTE << >> 13.2 CAMBIO DE VERSIONES




No hay comentarios:

Publicar un comentario