Serialize and deserialize objects and properties in Java

2

I have a problem with the serialization and deserialization of objects in Java, and I think it's because I do not really understand how it works. My program consists of some spreadsheets as in Excel, but by console. I have a class "Book" and a class "Page":

In Book, I have declared a Page HashMap and in Page I have a String Hashmap (to simulate the cells). Now I want that book to be persistent and for that what I do is serialize the book object (instance of Book)

try {
    FileOutputStream fileOut =
    new FileOutputStream("H:\Users\thero\Desktop\bin\libro.bin");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(libro);
    out.close();
    fileOut.close();
    System.out.printf("Se ha guardado el libro correctamente");
}catch (IOException i) {
     i.printStackTrace();
}

This code is included in a method of a class called "Save" that I call from the main. In parallel I have a class "Load" with the opposite method:

try {
     FileInputStream fileIn = new FileInputStream("H:\Users\thero\Desktop\bin\libro.bin");
     ObjectInputStream in = new ObjectInputStream(fileIn);
     libro = (Book) in.readObject();
     in.close();
     fileIn.close();
} catch (IOException i) {
     i.printStackTrace();
} catch (ClassNotFoundException ex) {
     Logger.getLogger(Cargar.class.getName()).log(Level.SEVERE, null, ex);
}

This method I also call from the main, and when executing it, no exception jumps. However, it seems that it only loads the instance of Book, but does not load the Hashmap property, and therefore does not load the created sheets or the cells or anything. Where is the problem? Thanks

    
asked by theroxd4n 08.12.2018 в 18:57
source

1 answer

1

First of all, serialization is to convert an object or set of these bits to treat them in different computer applications, either to store them in files, or send them through sockets (roughly, by the network). You can serialize any object, as long as it is inherited from the Serializable interface.

The advantage of HashMap is that it has already implemented Serializable , so we can serialize all the HashMap at once, with all its data and internal attributes, so when you open the program, just is to open the flow, read and assign, close the flows and the buffer and you're done.

An example in Java code is the following:

private HashMap<Integer, Persona> personas = new HashMap<Integer, Persona>();

We have a HashMap , which the primary key will be of the class Integer or integer, and the content will be of the class Persona . To save you can use the following:

public boolean add(int edad, String nombre){
        Persona p = new Persona(edad, nombre);
        return personas.put(personas.size()+1, p) != null;
}

Up to this point it only saves in memory, to save in the file do the following:

    public void guardar(){
        try {
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(this.personas);
            oos.close();
            fos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

The add and save method can be merged if you want. The whole class where all the serialization is is as follows:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Carlos
 */
public class Gestion {
    private HashMap<Integer, Persona> personas = new HashMap<Integer, Persona>();
    private File file;
    private FileInputStream fis;
    private FileOutputStream fos;
    private ObjectInputStream ois;
    private ObjectOutputStream oos;

    public Gestion(String ruta) {
        this.file = new File(ruta);
        this.crearArchivo();
    }
    public boolean add(int edad, String nombre){
        Persona p = new Persona(edad, nombre);
        return personas.put(personas.size()+1, p) != null;
    }

    public HashMap<Integer, Persona> obtenerTodo() {
        try {
            HashMap<Integer, Persona> personasTemp = new HashMap<>();
            boolean buffer = false;
            fis = new FileInputStream(file);
            while (fis.available() > 0) {
                ois = new ObjectInputStream(fis);
                Persona p = (Persona) ois.readObject();
                if (p != null) {
                    personasTemp.put(personasTemp.size() + 1, p);
                }
                buffer = true;
            }
            if (buffer) {
                ois.close();
            }
            fis.close();
            return personasTemp;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println(e);
            return null;
        }

    }

    public void obtener(){
        try {
            fis = new FileInputStream(file);
            boolean buffer = false;
            while(fis.available() > 0){
                ois = new ObjectInputStream(fis);
                HashMap<Integer, Persona> personasTemp = (HashMap<Integer, Persona>) ois.readObject();
                if (personasTemp != null){
                    this.personas = personasTemp;
                }
                buffer = true;
            }
            if (buffer){
                ois.close();
            }
            fis.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void guardar(){
        try {
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(this.personas);
            oos.close();
            fos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void crearArchivo() {
        if(!this.file.exists()){
            try {
                file.createNewFile();
            } catch (IOException ex) {
                Logger.getLogger(Gestion.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void imprimirTodo(){
        if(this.personas.isEmpty()){
            System.out.println("No hay nada...");
            return;
        }
        for(int i = 0 ; i < this.personas.size(); i++){
            System.out.println(personas.get(i+1));
        }
    }
}

The people class is the following:

import java.io.Serializable;
import java.util.Objects;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Carlos
 */
public class Persona implements Serializable{

    private static final long serialVersionUID = 1L;
    private int edad;
    private String nombre;

    public Persona(int edad, String nombre) {
        this.edad = edad;
        this.nombre = nombre;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + this.edad;
        hash = 59 * hash + Objects.hashCode(this.nombre);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Persona other = (Persona) obj;
        if (this.edad != other.edad) {
            return false;
        }
        if (!Objects.equals(this.nombre, other.nombre)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Persona{" + "edad=" + edad + ", nombre=" + nombre + '}';
    }



}

And finally the Main or main class, which is where the Main is, is the following:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Carlos
 */
public class Main {
    private final Gestion gestion;
    public Main() {
        this.gestion = new Gestion("ejemplo.bin");
        /*this.gestion.add(25, "Carlos");
        this.gestion.add(20, "Juan");
        this.gestion.add(19, "Pepe");
        this.gestion.guardar();*/
        this.gestion.imprimirTodo();
        this.gestion.obtener();
        this.gestion.imprimirTodo();
    }



    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Main m = new Main();
    }

}
    
answered by 10.12.2018 в 05:08