viernes, 8 de julio de 2011

Archivos


Características y ejemplos de las diferentes formas de almacenar estructuras de datos.

Archivos Secuenciales:
      La forma más común de estructura de archivo es el archivo secuencial. En este tipo de archivo, un formato  fijo es usado para los registros. Todos los registros tienen el mismo tamaño, constan del mismo número de campos de tamaño fijo en un orden particular. Como se conocen la longitud y la posición de cada campo, solamente los valores de los campos se necesitan almacenarse; el nombre del campo y longitud de cada campo son atributos de la estructura de archivos.

      Un campo particular, generalmente el primero de cada registro se conoce como el campo clave. El campo clave identifica unívocamente al registro. así, los valores de la clave para registros diferentes son siempre diferentes.

        Los archivos secuenciales son típicamente utilizados en aplicaciones de proceso de lotes Y son óptimos para dichas aplicaciones si se procesan todos los registros. La organización secuencias de archivos es la única que es fácil de usar tanto en disco como en cinta.

       Para las aplicaciones interactivas que incluyen peticiones o actualizaciones de registros individuales, los archivos secuenciales ofrecen un rendimiento pobre.

     Normalmente un archivo secuencial se almacena en bloques, en un orden secuencial simple de los registros. La organización física del archivo en una cinta o disco se corresponde exactamente con la ubicación lógica del archivo. En este caso, el procedimiento para ubicar los nuevos registros en un archivo de pila separado, llamado archivo de registro (log file) o archivo de transacciones. Periódicamente, se realiza una actualización por lotes que mezcla el archivo de registro con el archivo maestro para producir un nuevo archivo en secuencia correcta de claves.
Ejemplo:

Registro 1
Registro 2

Registro |-1
Registro |-2

Registro N-1
Registro N




Archivos Indexados:
   Los archivos secuenciales indexados retienen la limitación del archivo secuencial: la eficacia en el procesamiento se limita al basado en un único campo del archivo. Cuando es necesario buscar un registro basándose en algún otro atributo distinto del campo clave ambas formas de archivo secuencial no son adecuadas. En algunas aplicaciones esta flexibilidad es deseable.

       Para alcanzar esta flexibilidad, se necesita una estructura que utilice múltiples índices, uno para cada tipo de campo que pueda ser objeto de la búsqueda.

      Se suelen utilizar dos tipos de índices. Uno índice exhaustivo contiene una entrada par cada registro del archivo principal. Otro índice parcial contendrá entradas a los registros donde este el campo de interés. Con registros de longitud variable, algunos registros no contendrán todos los campos.

    Los archivos indexados son muy utilizados en aplicaciones donde es crítica la oportunidad de la información y donde los datos son rara vez procesados de forma exhaustiva.


Ejemplo:


Vamos a mostrar un ejemplo para tratar de entender correctamente esta organización de archivo.
Supongamos un archivo de datos personales de los alumnos que conste de estos 10 registros:
DNI (clave)    Nombre         Teléfono
1111        Arturo Pérez       348734
1232        Miguel Ruiz        349342
2100        Antonia Camacho    209832
2503        Silvia Ortiz       349843
3330        Sonia del Pino     987349
5362        José Anguita       978438
6300        Ana Zamora         476362
6705        Susana Hernández   473239
7020        Rodrigo Sánchez    634838
9000        Natalia Vázquez    362653
Imaginemos que cada segmento tiene 4 registros. Por lo tanto, el archivo se dividirá en 3 segmentos. Si suponemos que cada registro ocupa 50 bytes en memoria secundaria, y que el principio del archivo está en la dirección 100 de dicha memoria, el archivo físico tendrá este aspecto:
Área primaria:
Dirección   Clave (DNI)    Contenido del registro   
 física
100          1111         Arturo Pérez     348734
  150          1232         Miguel Ruiz      349342
  200          2100         Antonia Camacho  209832
  250          2503         Silvia Ortiz     349843
  300          3330         Sonia del Pino   987349
  350          5362         José Anguita     978438
  400          6300         Ana Zamora       476362
  450          6705         Susana Hernández 473239
  500          7020         Rodrigo Sánchez  634838
  550          9000         Natalia Vázquez  362653
  600        Sin usar       
  650        Sin usar
Área de índices:
Segmento    Dirección    Clave del útimo
           de comienzo       registro
1            100            2503
  2            300            6705
  3            500            9000
Observe primero el área primaria: los registros están dispuestos en orden creciente según la clave (que, en este caso, es el campo NIF). A la izquierda aparece la dirección física donde comienza cada registro. Fíjate también en que los registros están agrupados en tres segmentos.
Luego fíjese en el área de índices: contienen una lista de segmentos, guardando la dirección de comienzo del segmento y la clave del último registro de ese segmento.
Para acceder, por ejemplo, al registro cuya clave es 5362, el proceso es el siguiente:
  1. Buscar en el área de índices secuencialmente, es decir, desde la primera fila, hasta localizar un registro mayor que el que estamos buscando. Eso ocurre en la segunda fila, pues la clave del último registro es 6705. Por lo tanto, sabemos que el registro buscado debe de estar en el segmento 2.
  2. Acceder de forma directa a la dirección 300 del área primaria, que es de comienzo del segmento 2. Esa dirección la conocemos gracias a que está guardada en el área de índices.
  3. Buscar en el área primaria secuencialmente a partir de la dirección 300, hasta localizar el registro buscado, que ocupa la segunda posición dentro de ese segmento.
Fíjese en que han sido necesarios, en total, 4 accesos secuenciales y 1 directo. Si hubiésemos hecho una búsqueda secuencial, hubiéramos necesitado 6 accesos secuenciales desde el principio del archivo. Esto puede no parecer una gran ventaja, pero ahora piensa qué pasaría si el archivo tuviera más segmentos y el registro buscado estuviera muy lejos del principio del archivo. Cuanto mayor es el tamaño del archivo y más lejos del principio está el registro, más ventajosa resulta la organización indexada frente a la secuencial. 




Archivos Directos o de Dispersión:
    Los archivos directos o de dispersión explotan la capacidad de los discos para acceder directamente a cualquier bloque de dirección conocida. Requiere de un campo clave en cada registro pero no incorpora el sentido de secuencia.

   El archivo directo hace uso de las técnicas de dispersión que ya vimos en Administración de Memoria Virtual. Estos archivos son utilizados en aplicaciones que requieren acceso muy rápido, que usan registros de longitud fija y donde siempre se accede de a un registro por ves: guías telefónicas, padrones, tablas de precios, etc. 

  • Explotan la capacidad de los discos para acceder directamente a cualquier bloque de dirección conocida.
  • Se requiere un campo clave en cada registro.
  • Los archivos directos son muy usados donde se necesita un acceso muy rápido, donde se usan registros de longitud fija y donde siempre se accede a los registros de una vez.
Ejemplo:

La función fseek() sirve para situarnos directamente en cualquier posición del fichero, de manera que el resto de lecturas se hagan a partir de esa posición. Su prototipo es:
int fseek(FILE* puntero_a_archivo, long int num_bytes, int origen);
El argumento origen debe ser una de estas tres constantes definidas en stdio.h:
  • SEEK_SET: principio del fichero
  • SEEK_CUR: posición actual
  • SEEK_END: final del fichero
El argumento num_bytes especifica en qué posición desde el origen queremos situarnos. Por ejemplo, con esta llamada nos colocamos en el byte número 500 contando desde el principio del archivo:
fseek(archivo, 500, SEEK_SET);
Y con esta otra nos desplazamos 2 bytes más allá de la posición actual:
fseek(archivo, 2, SEEK_CUR);
Esta función devuelve 0 si se ejecuta correctamente o cualquier otro valor si ocurre algún error.
La función ftell(), por su parte, devuelve el indicador de posición del archivo, es decir, cuántos bytes hay desde el principio del archivo hasta el lugar donde estamos situados en ese momento. Su prototipo es:
long int ftell(FILE* puntero_a_archivo);
Devuelve -1 si se produce un error.
Un uso habitual de la función ftell() es averiguar el tamaño de un archivo, de este modo:
fseek(archivo, 0, SEEK_END);
tam_archivo = ftell(archivo);
Es decir, primero nos colocamos al final del archivo con fseek(), y luego preguntamos a ftell() el byte en el que nos hemos situado (contando desde el comienzo del archivo). Como resultado, ftell() nos proporcionará en tamaño (en bytes) del archivo.


No hay comentarios:

Publicar un comentario