Tarea 16: Añadir Objetos a un Fichero Existente con MiObjectOutputStream
Explicación del Ejercicio
En esta tarea se añaden dos alumnos más a alumnos.dat sin perder los ya guardados. El problema es que ObjectOutputStream escribe siempre una cabecera al crearse; si se abre el fichero en modo añadir, esa cabecera se escribe de nuevo en mitad del fichero y la lectura posterior falla. La solución es una subclase propia que no la escriba.
Conceptos y métodos clave:
-
Subclase
MiObjectOutputStream: Hereda deObjectOutputStreamy redefinewriteStreamHeader()con un cuerpo vacío, de forma que no se escribe ninguna cabecera. -
Modo añadir (
new FileOutputStream(fichero, true)): El segundo parámetro evita que el fichero se sobrescriba y coloca la escritura al final. -
Variable
existe: Se guarda el resultado deexists()antes de abrir el flujo, porque al abrir unFileOutputStreamel fichero se crea y la comprobación posterior siempre daríatrue. -
Elección del flujo: Si el fichero ya existía se usa
MiObjectOutputStream; si no, unObjectOutputStreamnormal que sí escribe la cabecera. -
Comprobación: Al final se lee el fichero completo con
ObjectInputStreamy aparecen los 7 alumnos: los 5 originales y los 2 nuevos.
Código Fuente y Salida
MiObjectOutputStream.java
package ClaseFile;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
* @author Eva Gallardo Romero
* @date 29 de sep de 2026
* Subclase de ObjectOutputStream que no escribe la cabecera del fichero.
* Se usa para añadir objetos a un fichero que ya tiene cabecera.
*/
public class MiObjectOutputStream extends ObjectOutputStream {
public MiObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
protected MiObjectOutputStream() throws IOException, SecurityException {
super();
}
// redefino el método para que no escriba la cabecera
@Override
protected void writeStreamHeader() throws IOException {
}
}
Clase15.java
package ClaseFile;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @author Eva Gallardo Romero
* @date 29 de sep de 2026
* Añadir dos alumnos más al final del fichero "alumnos.dat" sin perder los
* que ya estaban guardados. Si el fichero ya existe hay que usar la clase
* MiObjectOutputStream para que no se escriba otra cabecera. Después se
* lee el fichero completo para comprobar que se han añadido.
*/
public class Clase15 {
public static void main(String[] args) {
// objeto File del fichero de objetos
File fichero = new File("alumnos.dat");
// guardo si existe ANTES de abrir el flujo, porque al abrirlo se crea
boolean existe = fichero.exists();
// alumnos nuevos que quiero añadir
Alumno[] nuevos = {new Alumno("Pablo", 24, 7.0), new Alumno("Sara", 21, 9.5)};
try (FileOutputStream fos = new FileOutputStream(fichero, true)) {
// si el fichero existe no puedo escribir otra cabecera
ObjectOutputStream oos;
if (existe) {
oos = new MiObjectOutputStream(fos);
} else {
oos = new ObjectOutputStream(fos);
}
for (int i = 0; i < nuevos.length; i++) {
oos.writeObject(nuevos[i]);
System.out.println("Añadido el alumno: " + nuevos[i].getNombre());
}
oos.close();
} catch (IOException e) {
System.out.println("Error al añadir los objetos: " + e.getMessage());
return;
}
// leo el fichero completo para comprobar el resultado
System.out.println("\nContenido actual de " + fichero.getName() + ":");
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fichero))) {
try {
while (true) {
Alumno alumno = (Alumno) ois.readObject();
System.out.printf("Nombre: %s, edad: %d, nota: %.2f %n",
alumno.getNombre(), alumno.getEdad(), alumno.getNota());
}
} catch (EOFException eof) {
System.out.println("FIN DE LECTURA");
}
} catch (IOException | ClassNotFoundException e) {
System.out.println("Error al leer los objetos: " + e.getMessage());
}
}
}
Resultado Mostrado por Terminal
Salida de Consola
Añadido el alumno: Pablo
Añadido el alumno: Sara
Contenido actual de alumnos.dat:
Nombre: Lucía, edad: 20, nota: 8.50
Nombre: Carlos, edad: 22, nota: 6.00
Nombre: Marta, edad: 21, nota: 9.25
Nombre: Javier, edad: 23, nota: 7.50
Nombre: Elena, edad: 20, nota: 5.75
Nombre: Pablo, edad: 24, nota: 7.00
Nombre: Sara, edad: 21, nota: 9.50
FIN DE LECTURA