Manejo de archivos de registros con gestión de lista de huecos

Solución a la práctica propuesta en la asignatura de “Teoría de la Gestión de la Información” de la UPM.

El objetivo de esta práctica es implementar las clases Java necesarias para disponer del manejo de archivos de registros, almacenados en disco, que permitan la lectura, inserción y borrado de registros, incorporando la gestión de listas de huecos.

Enlace al enunciado de la práctica

Enlace a la solución propuesta en Java

Para comprender un poco mejor la gestión de la lista de huecos vemos el siguiente ejemplo:

En un primer momento no tendremos registros y, por tanto, nuestra cabecera de la lista de huecos tendrá el campo de control con valor -1.

Después de insertar el primer registro (en este ejemplo es un registro de películas), continuaremos con la cabecera de la lista de huecos a -1, y el registro 1 (la primera película insertada) tendrá como cabecera el valor -2 (que significa que el registro está ocupado).

Supongamos ahora que hemos insertado 5 registros de películas y queremos borrar uno de estos registros, el proceso es sencillo, queremos borrar el registro número 4, entonces nos posicionamos en ese registro (tamaño de un registro * posición) y almacenamos su cabecera en una variable auxiliar, el siguiente paso es intercambiar la cabecera de la lista de huecos por la cabecera del registro, así quedará en la cabecera de la lista de huecos el último registro borrado, en este caso el 4, y en donde anteriormente estaba el registro 4 su campo de control tendrá asignado el valor -1 (lo cual significa que es el final de la lista de huecos).

En caso de eliminar un registro después del 4, el proceso sería el mismo, ahora intercambiamos la cabecera de la lista de huecos por la cabecera del registro a eliminar, como anteriormente la cabecera de la lista de huecos nos indicaba que el primer hueco era la posición 4, ahora pasará a indicarnos que la primera posición (el último registro borrado) está en la posición 5, y el campo de control de la posición 5, nos dirá que el anterior a el es el 4.

A la hora de insertar lo único que debemos hacer es observar la cabecera de la lista de huecos (que nos indica el primer hueco donde insertar) en caso de ser está -1 significa que no hay huecos e insertamos al final del fichero, en caso contrario hemos de tomar la posición que nos indica la cabecera y acto seguido leer la cabecera en esa posición (que nos indicará si es el final, o si aún hay más huecos libres) y en el caso de que apunte a otro hueco hemos de actualizar la cabecera de la lista de huecos con ese valor.

Ejemplo gráfico:

1 -Archivo vacío:

********* volcado del contenido del archivo al crearlo **********************
Cabecera de la lista de huecos: -1. Registros en uso(ocupados+libres): 0
****************** FIN DEL VOLCADO ***********************
*****************************************************************************

2 – Añadimos el primer registro:

***********volcado después de añadir el primer registro********************
Cabecera de la lista de huecos: -1. Registros en uso(ocupados+libres): 1
Registro 1; RegistroPelicula [control=-2, numReg=40, titulo=Brave , tipo=animacion , anio=2012, duracion=130]
****************** FIN DEL VOLCADO ***********************
***************************************************************************

3 – Después de añadir 2 registros más:

***********volcado después de añadir tres registros************************
Cabecera de la lista de huecos: -1. Registros en uso(ocupados+libres): 3
Registro 1; RegistroPelicula [control=-2, numReg=40, titulo=Brave , tipo=animacion , anio=2012, duracion=130]
Registro 2; RegistroPelicula [control=-2, numReg=10, titulo=Avatar , tipo=accion , anio=2009, duracion=145]
Registro 3; RegistroPelicula [control=-2, numReg=30, titulo=La red social , tipo=drama , anio=2012, duracion=110]
****************** FIN DEL VOLCADO ***********************
***************************************************************************

4 – Después de borrar el registro en la posición 2:

***********volcado después de borrar el registro de la posición 2**********
Cabecera de la lista de huecos: 2. Registros en uso(ocupados+libres): 3
Registro 1; RegistroPelicula [control=-2, numReg=40, titulo=Brave , tipo=animacion , anio=2012, duracion=130]
Registro 2; RegistroPelicula [control=-1, numReg=10, titulo=Avatar , tipo=accion , anio=2009, duracion=145]
Registro 3; RegistroPelicula [control=-2, numReg=30, titulo=La red social , tipo=drama , anio=2012, duracion=110]
****************** FIN DEL VOLCADO ***********************
***************************************************************************

5 – Después de borrar el registro en la posición 3: (en este caso ya observamos que el registro 3 contiene la posición del anterior, el 2)

***********volcado después de borrar el registro de la posición 3**********
Cabecera de la lista de huecos: 3. Registros en uso(ocupados+libres): 3
Registro 1; RegistroPelicula [control=-2, numReg=40, titulo=Brave , tipo=animacion , anio=2012, duracion=130]
Registro 2; RegistroPelicula [control=-1, numReg=10, titulo=Avatar , tipo=accion , anio=2009, duracion=145]
Registro 3; RegistroPelicula [control=2, numReg=30, titulo=La red social , tipo=drama , anio=2012, duracion=110]
****************** FIN DEL VOLCADO ***********************
***************************************************************************

6 – Ahora añadimos otro registro y observamos el comportamiento:

***********volcado después de añadir otro registro********************
Cabecera de la lista de huecos: 2. Registros en uso(ocupados+libres): 3
Registro 1; RegistroPelicula [control=-2, numReg=40, titulo=Brave , tipo=animacion , anio=2012, duracion=130]
Registro 2; RegistroPelicula [control=-1, numReg=10, titulo=Avatar , tipo=accion , anio=2009, duracion=145]
Registro 3; RegistroPelicula [control=-2, numReg=40, titulo=The Matrix , tipo=accion , anio=2001, duracion=180]
****************** FIN DEL VOLCADO ***********************
***************************************************************************

9 thoughts on “Manejo de archivos de registros con gestión de lista de huecos”

  1. Muchísimas gracias Alejandro, explicación de 10 ;). Tenía un gran error que bien explicastes, creía que cuando el método getControl() me devolvía un -1 significaba que no había huecos y por tanto insertaba al final y que (mi gran error) la cabecera tenía que modificarla. Por esos mis métodos de escribir y borrar no llegaban a nada XD.

    1. De nada Pedro, es un placer saber que te he ayudado. En el código de mi solución no he implementado ningún método auxiliar de getControl() aunque puede resultar bastante útil hacerlo.

  2. En el metodo de longitud de registro, tanto de película como de director, tengo una duda, tu lo tienes así:

    VARIABLES:
    public static final int TAMANIO_TITULO = 30;
    public static final int TAMANIO_TIPO = 25;
    private static final int TAMANIO_ANIO = (Integer.SIZE/8);
    private static final int TAMANIO_DURACION = (Integer.SIZE/8);
    private String titulo;
    private String tipo;
    private int anio;
    private int duracion;

    METODO LONGITUD:

    public int longitudRegistro()
    {

    return RegistroPelicula.TAMANIO_TIPO*2 + RegistroPelicula.TAMANIO_TITULO*2 + RegistroPelicula.TAMANIO_ANIO + RegistroPelicula.TAMANIO_DURACION + super.longitudRegistro();
    }
    Sin embargo yo lo tengo de esta manera:
    VARIABLES:
    public static final int TAMANIO_TITULO = 30;
    public static final int TAMANIO_TIPO = 25*(Character.SIZE/8);
    private static final int TAMANIO_ANIO = (Integer.SIZE/8);
    private static final int TAMANIO_DURACION = (Integer.SIZE/8);
    private String titulo;
    private String tipo;
    private int anio;
    private int duracion;

    METODO LONGITUD:

    public int longitudRegistro()
    {

    return RegistroPelicula.TAMANIO_TIPO+ RegistroPelicula.TAMANIO_TITULO + RegistroPelicula.TAMANIO_ANIO + RegistroPelicula.TAMANIO_DURACION + super.longitudRegistro();
    }

    La manera en la que yo lo hice creo que tiene sentido pero realiza mal la operación. ¿Porque multiplicas por 2 el tamaño titulo y el tamaño tipo?

    Gracias.

    1. Hola Pedro, pues verás, en un principio lo que tu dices tiene todo el sentido del mundo, aunque si te fijas bien (y cuesta detectarlo) en los métodos de escritura que se nos proporcionan implementados el método que escribe las String en el fichero (escribirCadena()) usa el método writeChar y, como puedes observar en la documentación oficial http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html#writeChar(int) ese método escribe 2 bytes por cara carácter, de ahí que para la lectura tengamos que especificar que el tamaño de lo que leemos es exactamente el doble de su tamaño (ya que hemos de leer 2 bytes por carácter).

      Espero que te sirva de ayuda, un saludo =)

  3. Aaaa muchas gracias Alejandro por tu ayuda :)…si, cierto no había tenido en cuenta ese detalle y la verdad que ni me imaginaba que el error de lo q hacia se debía a eso XD.

    1. Hola David, lee la respuesta que le he puesto a Pedro, solamente tienes que hacer dos “for” que hagan las combinaciones entre los nodos, ej: 0x0, 0x1,0x2…,5×4,5×5. Y para cada una de esas combinaciones aplicarle el método desarrollado para resolver el primer apartado que devuelve el mejor camino entre esos dos nodos 🙂 un saludo.

  4. EYY Alejandro me han dicho que en este blog proporcionas ayuda y vengo a pedirte una. No se si ya la habrás cursado o la esta cursando pero tengo dudas con los métodos listar y clave cercana de la practica 3 de TGI. No creas que vengo a pedirte directamente el código pero si una orientación para llevarlo a cabo. El de listar lo llevo a así:
    */
    public void listar()throws IOException
    {

    int num,num2;
    boolean existe=false;
    int x=(int) archivoDatos.numRegistros();
    int[] posiciones = new int[x];
    for (int i=0; i<x;i++){
    posiciones[i]=0;
    }
    Registro regaux;
    for(int pos=0;pos<x;pos++){

    for (int i=1;i<x;i++)
    {
    archivoDatos.leerRegistro(i);
    num=((RegistroNumReg)archivoDatos.getRegistro()).getNumReg();
    for(int j=1;j<x;i++)
    {
    for(int g=0;gnum2)
    {
    num=num2;
    posiciones[pos]=j;
    }
    }
    }

    }
    }
    }

    Y el de la clave sinceramente no se por donde cogerlo. Si puedes darme una ayudita te lo agradecería Alejandro.

Leave a Reply to pedro Cancel Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.