20 septiembre 2012

Escribir y leer objetos de memoria en vez de texto

Para poder escribir objetos serializables en memoria, lo primero de todo, si no queremos que nos dé una NotSerializableException hemos de definir nuestros objetos propios implementando el interfaz implements Serializable. Con esto,  deberíamos de ser capaces de poder guardar cualquier tipo de objeto propio en fichero.

Puede ocurrir, que estemos en un proyecto gigantesco, y heredemos tipos de objetos de los cuales no tengamos ningún control  y no podamos definirlos como serializables.

Para evitar problemas, lo ideal sería que no incluyéramos ese objeto en el nuestro como un atributo, pero si nos es imposible, o sencillamente es muy útil u óptimo almacenar ese objeto en el nuestro para su uso interno, podemos evitar que se incluya en el objeto que se va a guardar en fichero marcándolo como transient. Claro está, que cuando vayamos a recuperar este objeto, ese atributo no estará disponible y será null si lo miramos con un debugger.

Tras esta breve introducción, paso a poner un ejemplito del uso de todo esto.



package es.snippetea;



import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class UtilsSerializacion{

      /**
       *
       * Método que escribe en memoria un objeto serializable
       *
       * @param path - Ruta de la carpeta
       * @param fileName - Nombre del fichero
       * @param o - Objeto a guardar
       * @throws IOException
       */
      public static void writeObject(String path, String fileName, Object o) 
                         throws IOException{
           
            FileOutputStream fos = null;
            File dir = new File(path);
           
            //Verificamos si existe ese directorio.
            if(!dir.exists()){
                  //Construimos las carpetas faltantes de la ruta.
                  dir.mkdirs();
            }
           
            //Ahora podemos crear el objeto FileOutputStream sin miedo.
            fos = new FileOutputStream(
                         path
                        +System.getProperty("file.separator")
                        +fileName);
           
            //Instanciamos un ObjectOutputStream, escribimos el objeto y cerramos.
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(o);
            oos.close();
      }
     
      /**
       *
       * Método que devuelve un objeto almacenado en un fichero de forma binaria.
       *
       * @param path - Ruta de la carpeta
       * @param fileName - Nombre del fichero
       * @return El objeto recuperado
       * @throws IOException - Si no encuentra ese objeto
       * @throws ClassNotFoundException - Si el tipo de objeto enviado, no existe. 
       * En este caso hemos  enviado un objeto genérico, pero admite cualquier 
       * tipo de objeto serializable.
       */
      public static Object readObject(String path, String fileName) 
                           throws IOException, ClassNotFoundException{
            FileInputStream fis = null;
            File file = new File( path
                                 +System.getProperty("file.separator")
                                 +fileName);
            Object o = null;
           
            //Verificamos si el fichero existe
            if(file.exists()){
                  //Abrimos el fichero y lo recuperamos
                  fis = new FileInputStream(file);
                  ObjectInputStream ois = new ObjectInputStream(fis);
                  o = ois.readObject();
            }else{
                  System.out.println("Fichero no encontrado");
            }
            return o;
      }
     
     
     
      /**
       *
       * Main de pruebas
       *
       * @param args - No usa
       */
      public static void main(String args[]) {

            System.out.println("Inicio");

            ObjetoHeredadoSinSerializar ohss = 
                      new ObjetoHeredadoSinSerializar("SinSerializar");
            ObjetoSerializable miObj = 
                      new ObjetoSerializable("Serializable", ohss);
            ObjetoSerializable miObjRecuperado = null;

            try {
                  UtilsSerializacion.writeObject("C:\\tmp", "miObjeto.tmp", miObj);
                  miObjRecuperado =
                             (ObjetoSerializable) UtilsSerializacion.readObject(
                                         "C:\\tmp",
                                         "miObjeto.tmp");

            } catch (IOException e) {
                  e.printStackTrace();
            } catch (ClassNotFoundException e) {
                  e.printStackTrace();
            }

            System.out.println("Mi objeto original: "+miObj);
            System.out.println("Mi objeto recuperado: "+miObjRecuperado);
            System.out.println("Final");
      }

}


/**
 * Objeto que el proyecto necesita por diversas razones.
 * No implementa Serializable, por lo tanto no podrá incluirse y tendrá que 
 * ser marcado como transient
 * @author icendrero
 */
class ObjetoHeredadoSinSerializar{
     
      //Atributos
      @SuppressWarnings("unused")
      public String name = "";
      @SuppressWarnings("unused")
      public String att02 = "Valores";
     
      //Constructor
      public ObjetoHeredadoSinSerializar(String name){
            this.name = name;
            this.att02 += String.valueOf(name);
      }
      public String toString(){
            return "(ObjetoHeredadoSinSerializar: "+name+" - "+att02+")";
      }
}

/**
 * Objeto serializable
 * @author icendrero
 */
class ObjetoSerializable implements Serializable{
     
      /**
       * Generado automaticamente.
       */
      private static final long serialVersionUID = -1558587958636216484L;
      //Atributos
      @SuppressWarnings("unused")
      private String value = "";
      @SuppressWarnings("unused")
      private transient ObjetoHeredadoSinSerializar ohss = null;
     
      //Constructor
      public ObjetoSerializable(String arg, ObjetoHeredadoSinSerializar ohss){
            this.value = arg;
            this.ohss = ohss;
      }
     
      public String toString(){
            return value+" - "+ohss;
      }
}

No hay comentarios:

Publicar un comentario