1.
Serialización y persistencia de objetos
La serialización
es la transformación de un objeto en una secuencia de bytes que pueden ser
posteriormente leídos para reconstruir el objeto original.
El objeto serializado pueda guardarse en un fichero o puede enviarse por
red para reconstruirlo en otro lugar. Puede crearse en un sistema Windows y
enviarlo, por ejemplo, a otro sistema que utilice Linux.
Guardar objetos de forma que existan cuando la aplicación haya terminado se
conoce como persistencia.
Para poder transformar el objeto en una secuencia de bytes, el objeto debe
ser serializable.
Un objeto es serializable si su clase implementa la interface Serializable.
La interface Serializable se encuentra en el paquete java.io Es una
interface vacía. No contiene ningún método.
public interface Serializable{}
Sirve para indicar que los objetos de la clase que lo implementa se pueden
serializar. Solo es necesario que una clase la implemente para que la máquina
virtual pueda serializar los objetos.
Si un objeto contiene atributos que son referencias a otros objetos éstos a
su vez deben ser serializables.
Todos los tipos básicos Java son serializables, así como los arrays y los
String.
2.
Persistencia de Objetos en Ficheros
Para escribir objetos en un
fichero binario en Java se utiliza la clase ObjectOutputStream derivada de
OutputStream.
Un objeto ObjectOutputStream se
crea a partir de un objeto FileOutputStream asociado al fichero.
El constructor de la clase es:
ObjectOutputStream(OutputStream nombre);
Lanza una excepción IOException.
Por ejemplo, las instrucciones para crear el
fichero personas.dat para escritura de objetos serían éstas:
FileOutputStream fos = new FileOutputStream ("/ficheros/personas.dat");
ObjectOutputStream salida = new ObjectOutputStream (fos);
La clase proporciona el método
writeObject(Object objeto) para escribir el objeto en el fichero.
Lanza una IOException
El método defaultWriteObject() de la clase ObjectOutputStream realiza de forma automática la serialización
de los objetos de una clase. Este método se invoca en el método writeObject().
defaultWriteObject() escribe
en el stream de salida todo lo necesario para reconstruir los objetos:
- La clase del objeto.
- Los miembros de la clase (atributos).
- Los valores de los atributos que no sean static
o transient.
El método defaultReadObject() de la clase ObjectInputStream realiza la deserialización
de los objetos de una clase. Este método se invoca en el método readObject().
Ejemplo 1:
Ejemplo de persistencia de objetos en fichero en Java
Programa que escribe 3 objetos de
tipo Persona en el fichero personas.dat.
La clase Persona es la siguiente:
//Clase Persona
import java.io.Serializable;
public class Persona implements Serializable{
private String nif;
private String nombre;
private int edad;
public Persona() {
}
public Persona(String nif, String nombre, int edad) {
this.nif = nif;
this.nombre = nombre;
this.edad = edad;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
public String getNif() {
return nif;
}
public void setNif(String nif) {
this.nif = nif;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
//Clase Principal
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Serial1 {
public static void main(String[] args) {
FileOutputStream fos = null;
ObjectOutputStream salida = null;
Persona p;
try {
//Se crea el fichero
fos = new FileOutputStream("/ficheros/personas.dat");
salida = new ObjectOutputStream(fos);
//Se crea el primer objeto Persona
p = new Persona("12345678A","Lucas González", 30);
//Se escribe el objeto en el fichero
salida.writeObject(p);
//Se crea el segundo objeto Persona
p = new Persona("98765432B","Anacleto Jiménez", 28);
//Se escribe el objeto en el fichero
salida.writeObject(p);
//Se crea el tercer objeto Persona
p = new Persona("78234212Z","María Zapata", 35);
//Se escribe el objeto en el fichero
salida.writeObject(p);
} catch (FileNotFoundException e) {
System.out.println("1"+e.getMessage());
} catch (IOException e) {
System.out.println("2"+e.getMessage());
} finally {
try {
if(fos!=null){
fos.close();
}
if(salida!=null){
salida.close();
}
} catch (IOException e) {
System.out.println("3"+e.getMessage());
}
}
}
}
3. Serialización
y Herencia
Para serializar objetos
de una jerarquía solamente la clase base tiene que implementar el interface
Serializable. No es
necesario que las clases derivadas implementen la interfaz.
Si una clase es
serializable lo son también todas sus clases derivadas.
Ejemplo 2:
Ejemplo de herencia y
serialización:
Programa Java que escribe en un fichero tres objetos de tipo Empleado.
Empleado es una clase derivada de la clase Persona del ejemplo anterior. Como
la clase Persona es serializable, no es necesario indicar que la clase Empleado
también lo es. Empleado es serializable por el hecho de heredar de Persona.
//Clase Empleado
public class Empleado extends Persona{
private double sueldo;
public Empleado(String nif, String nombre, int edad, double sueldo) {
super(nif, nombre, edad);
this.sueldo = sueldo;
}
public Empleado() {
}
public double getSueldo() {
return sueldo;
}
public void setSueldo(double sueldo) {
this.sueldo = sueldo;
}
}
//Clase principal
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Serial3 {
public static void main(String[] args) {
FileOutputStream fos = null;
ObjectOutputStream salida = null;
Empleado emp;
try {
fos = new FileOutputStream("/ficheros/personas.dat");
salida = new ObjectOutputStream(fos);
emp = new Empleado("12345678A","Lucas González", 30, 1200.40);
salida.writeObject(emp);
emp = new Empleado("98765432B","Anacleto Jiménez", 28, 1000);
salida.writeObject(emp);
emp = new Empleado("78234212Z","María Zapata", 35, 1100.25);
salida.writeObject(emp);
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if(fos!=null) fos.close();
if(salida!=null) salida.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
4.
Serialización y clases compuestas
Cuando una clase contiene un atributo que es una referencia a otro
objeto, la clase a la que pertenece dicho atributo también debe ser
serializable.
Ejemplo 3:
Ejemplo de
serialización de una clase compuesta:
Programa java que escribe en un fichero tres objetos de tipo Alumno.
Alumno es una clase derivada de Persona y contiene un atributo Fecha:
//Clase Fecha
import java.io.Serializable;
public class Fecha implements Serializable{
private int dia;
private int mes;
private int año;
public Fecha(int dia, int mes, int año) {
this.dia = dia;
this.mes = mes;
this.año = año;
}
public Fecha() {
}
public int getAño() {
return año;
}
public void setAño(int año) {
this.año = año;
}
public int getDia() {
return dia;
}
public void setDia(int dia) {
this.dia = dia;
}
public int getMes() {
return mes;
}
public void setMes(int mes) {
this.mes = mes;
}
}
//Clase Alumno
public class Alumno extends Persona{
private Fecha fechaMatricula;
public Alumno(String nif, String nombre, int edad, Fecha fechaMatricula) {
super(nif, nombre, edad);
this.fechaMatricula = new Fecha();
setFechaMatricula(fechaMatricula);
}
public Alumno() {
}
public Fecha getFechaMatricula() {
return fechaMatricula;
}
public void setFechaMatricula(Fecha fechaMatricula) {
this.fechaMatricula.setDia(fechaMatricula.getDia());
this.fechaMatricula.setMes(fechaMatricula.getMes());
this.fechaMatricula.setAño(fechaMatricula.getAño());
}
}
//Clase principal
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Serial5 {
public static void main(String[] args) {
FileOutputStream fos = null;
ObjectOutputStream salida = null;
Alumno a;
Fecha f;
try {
fos = new FileOutputStream("/ficheros/alumnos.dat");
salida = new ObjectOutputStream(fos);
f = new Fecha(5,9,2011);
a = new Alumno("12345678A","Lucas González", 20, f);
salida.writeObject(a);
f = new Fecha(7,9,2011);
a = new Alumno("98765432B","Anacleto Jiménez", 19, f);
salida.writeObject(a);
f = new Fecha(8,9,2011);
a = new Alumno("78234212Z","María Zapata", 21, f);
salida.writeObject(a);
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if(fos!=null) fos.close();
if(salida!=null) salida.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
5.
Leer objetos de ficheros
Para leer los objetos contenidos en un fichero binario que han sido
almacenados mediante ObjectOutputStream se utiliza la clase ObjectInputStream derivada de
InputStream.
Un objeto ObjectInputStream se crea a partir de un objeto
FileInputStream asociado al fichero.
El constructor de la clase es:
ObjectInputStream(InputStream nombre);
Lanza una excepción IOException.
Por Ejemplo, las instrucciones para crear el objeto
ObjectInputStream para lectura de objetos del fichero personas.dat serían
éstas:
FileInputStream fis = new FileInputStream ("/ficheros/personas.dat");
ObjectInputStream entrada = new ObjectInputStream (fis);
La clase proporciona el método readObject() que devuelve el objeto del
fichero (tipo Object).
Es necesario hacer un casting para guardarlo en una variable del tipo
adecuado.
Lanza una IOException
Ejemplo 4:
Ejemplo de lectura de
objetos contenidos en un fichero en Java
Programa que lee los objetos del fichero creado en el Ejemplo 1:
//Clase principal
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Serial2 {
public static void main(String[] args) {
FileInputStream fis = null;
ObjectInputStream entrada = null;
Persona p;
try {
fis = new FileInputStream("/ficheros/personas.dat");
entrada = new ObjectInputStream(fis);
p = (Persona) entrada.readObject(); //es necesario el casting
System.out.println(p.getNif() + " " + p.getNombre() + " " + p.getEdad());
p = (Persona) entrada.readObject();
System.out.println(p.getNif() + " " + p.getNombre() + " " + p.getEdad());
p = (Persona) entrada.readObject();
System.out.println(p.getNif() + " " + p.getNombre() + " " + p.getEdad());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (entrada != null) {
entrada.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Ejemplo 5:
Programa Java que lee los objetos del fichero creado en el Ejemplo 2:
//Clase Principal
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Serial4 {
public static void main(String[] args) {
FileInputStream fis = null;
ObjectInputStream entrada = null;
Empleado emp;
try {
fis = new FileInputStream("/ficheros/personas.dat");
entrada = new ObjectInputStream(fis);
emp = (Empleado) entrada.readObject();
System.out.println(emp.getNif() + " "
+ emp.getNombre() + " " + emp.getEdad() + " " + emp.getSueldo());
emp = (Empleado) entrada.readObject();
System.out.println(emp.getNif() + " "
+ emp.getNombre() + " " + emp.getEdad() + " " + emp.getSueldo());
emp = (Empleado) entrada.readObject();
System.out.println(emp.getNif() + " "
+ emp.getNombre() + " " + emp.getEdad() + " " + emp.getSueldo());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (entrada != null) {
entrada.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Ejemplo 6:
Programa Java que lee los objetos del fichero creado en el Ejemplo 3:
//Clase Principal
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import persona.Alumno;
public class Serial6 {
public static void main(String[] args) {
FileInputStream fis = null;
ObjectInputStream entrada = null;
Alumno a;
try {
fis = new FileInputStream("/ficheros/alumnos.dat");
entrada = new ObjectInputStream(fis);
a = (Alumno) entrada.readObject();
System.out.println(a.getNif() + " " + a.getNombre() + " " + a.getEdad()
+ " " + a.getFechaMatricula().getDia() + "-"
+ a.getFechaMatricula().getMes() + "-"
+ a.getFechaMatricula().getAño());
a = (Alumno) entrada.readObject();
System.out.println(a.getNif() + " " + a.getNombre() + " " + a.getEdad()
+ " " + a.getFechaMatricula().getDia() + "-"
+ a.getFechaMatricula().getMes() + "-"
+ a.getFechaMatricula().getAño());
a = (Alumno) entrada.readObject();
System.out.println(a.getNif() + " " + a.getNombre() + " " + a.getEdad()
+ " " + a.getFechaMatricula().getDia() + "-"
+ a.getFechaMatricula().getMes() + "-"
+ a.getFechaMatricula().getAño());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (entrada != null) {
entrada.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
6. El modificador transient
Un atributo transient no se serializa.
En el siguiente ejemplo,
la clase Cliente tiene
dos atributos: el nombre del cliente y la contraseña. El atributo contraseña es
transient por lo tanto si se serializa para escribir un objeto Cliente en un
fichero solo se escribirá el atributo nombre.
//Clase Cliente
public class Cliente implements Serializable{
private String nombre;
private transient String passWord;
public Cliente(String nombre, String passWord) {
this.nombre=nombre;
this.passWord= passWord;
}
}
El archivo al que se hace la referencia (alumnos.dat). Es un archivo que debo tner guardado en la carpeta de mi proyecto o a que se refiere esa parte? estoy confundida..
ResponderEliminarfis = new FileInputStream("/ficheros/alumnos.dat");
Esta instrucción indica que el fichero alumnos.dat está dentro de una carpeta llamada ficheros que debe estar en la raíz de la unidad donde se encuentra en proyecto. Si estás trabajando con un proyecto que tienes en el pendrive la carpeta ficheros debe estar en la raiz del pendrive.
EliminarEstoy ocupando netBeans, en que parte debo agregar la carpeta "ficheros"???? Gracias
EliminarMe podrias orientar para que el siguiente codigo pueda realizar la consulta a traves dell DNI o numero de expediente:
ResponderEliminarprivate 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();
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){}
}
Por Favor me podrias ayudar con esto? Urgente Gracias
ResponderEliminarConstruir Servidor de paginas web con funcionalidades basicas que pueda atender solicitudes hechas por varias instancias de navegador(cliente) al mismo tiempo.
Instala un Tomcat y listo....
EliminarPor favor, ayuda estoy intentado para un vector de objetos y no sale :c
ResponderEliminarQue pasa si en lugar de ir metiendo objeto por objeto quiero meter un arreglo de objetos, ya lo intente y no me lo permite
ResponderEliminarpublic void ward(String name){
try{
FileOutputStream fout= new FileOutputStream(name);
ObjectOutputStream oos=new ObjectOutputStream(fout);//objecto para mandar a escribir al archivo
for(k=0;k<=index;k++)
{
oos.writeObject(libros[k]); //el problema es acá
}
oos.close();
}catch(EOFException e){
e.printStackTrace();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
alguna alma caritativa me puede ayudar .Cuando pone en leer el primer ejercicio binario :
ResponderEliminar"//es necesario el casting" que deobo poner por que me atasque y no doy con ello
muchas gracias y perdon por las molestias
public void ejecute(String aux){
ResponderEliminarStatement sentencias=null;
try{
sentencias = conn1.createStatement();
sentencias.executeUpdate(aux);
sentencias.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
public void leersql(String fichero){
String aux;
try{
String cadena;
aux="";
FileReader f = new FileReader(fichero);
BufferedReader b = new BufferedReader(f);
while((cadena = b.readLine())!=null) {
if(cadena.startsWith("/*")||cadena.startsWith("--")){
}else{
if(!cadena.endsWith(";")){
aux+=cadena;
}
if(cadena.endsWith(";")){
aux+=cadena;
ejecute(aux);
aux="";
}
}
}
System.out.println("Treminado");
b.close();
f.close();
}
catch (IOException e){
System.out.println(e.getStackTrace());
}
}
public void altaReparaciones(){
String fechaE,fechaS;
ArrayList matriculas=new ArrayList();
System.out.print("Fecha de entrada (dd/mm/aa): ");
fechaE=sc.next();
System.out.print("Fecha de salida (dd/mm/aa): ");
fechaS=sc.next();
System.out.println("Listado de coches:");
System.out.println("--------------------------");
try{
int contador=0,cocheSelec=0,precio,cantidad;
String SQL = "SELECT * FROM coches",nombre;
Statement stmt = conn1.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
while (rs.next()) {
contador++;
matriculas.add(rs.getString("matricula"));
System.out.println(contador+", "+rs.getString("matricula") + ", " + rs.getString("marca")+", "+rs.getString("modelo"));
}
System.out.println("Elige uno de los coches:");
cocheSelec=sc.nextInt();
PreparedStatement ps=null;
ps=conn1.prepareStatement("INSERT INTO `reparaciones` VALUES (NULL,?,?,?)");
ps.setString(1, fechaE);
ps.setString(2, fechaS);
ps.setString(3, matriculas.get(cocheSelec-1));
ps.executeUpdate();
ps.close();
System.out.println("Reparacion dada de alta, inserta los materiales usados");
System.out.println("-----------------------------------------");
System.out.print("Nombre:");
nombre=sc.next();
System.out.print("Cantidad:");
cantidad=sc.nextInt();
System.out.print("Precio:");
precio=sc.nextInt();
rs.close();
stmt.close();
}catch(Exception e){
}
}