Tabla de fichas Indice del Tema 1001
1001 1002 1003 1004 1005 1006 1007 1008

ARCHIVOS





Generalidades
En primera aproximación, la potencia de una computadora viene determinada dos factores primordiales:
Este panorama es real, pero no contempla un detalle fundamental: ¿de dónde proviene la información (tanto datos como programas)? Podría pensarse en una conexión de red, y el resultado son las "diskless workstations", estaciones de trabajo que toman su información de otras máquinas a través de la red. Pero esto solo traslada el problema: ¿de dónde proviene la información existente en esas otras máquinas? La respuesta es, claramente, el subsistema de almacenamiento masivo, que se caracteriza por un coste por megabyte muy reducido en comparación con los precios de RAM, y por ser permanente: aun cuando se corte la alimentación del subistema, su contenido permanecerá inalterado, a diferencia de la RAM, cuyo contenido desaparece con la alimentación.
Concretando, el subsistema de memoria permanente se organiza de tal modo que las aplicaciones y los datos se almacenan en bloques llamados archivos. Esos archivos tienen un nombre, que se utiliza para accede a ellos. Como el número de archivos suele ser elevado, es preciso organizarlos, y de eso se encarga el sistema de archivos empleado.
El manejo de archivos plantea dificultades similares a las que aparecen a la hora de leer información del teclado o imprimir información en pantalla. A diferencia de la pantalla, un archivo no tiene "anchura máxima", y se pueden formar "líneas" tan largas como se desee. Los archivos, a diferencia de las hojas de papel en que uno tiende a pensar cuando se habla de información escrita, no tienen "ancho", ni "largo"; ni siquiera existe el concepto de línea o de hoja. Sólo hay, por así decir, una línea de información tan larga como se quiera. Será responsabilidad de la aplicación que lea ese archivo mostrarlo con formato "humano", esto es, en la forma de líneas, párrafos y páginas que estamos acostumbrados a manejar.
Habida cuenta de que no hay restricciones en lo tocante a escritura, escribir va a ser una tarea "sencilla": el archivo lo admite todo. Los problemas vienen, sin embargo, a la hora de leer lo escrito. Leer información de un archivo conlleva dos tareas: Cuanto más regular y sencillo sea el formato empleado al escribir, más fácil resultará la lectura. En todo caso, será preciso definir y seguir una convención para el almacenamiento y recuperación de datos en disco: a esto se le da el nombre de formato del archivo. Una vez conocido el formato, es posible realizar la lectura.

Definición de archivo.
Desde el punto de vista de C, un archivo es una colección numerada y ordenada de bytes. Es posible leer o escribir a partir de cualquiera de las posiciones de memoria de que consta el archivo, y también es posible añadir información al archivo o imponer un fin de archivo en alguna posición anterior a su situación actual (salvo archivos vacíos, claro).
El nombre del archivo puede emplearse para indicar al sistema operativo, y a las aplicaciones, la forma en que se ha organizado el contenido del archivo. Según su contenido, existen dos tipos genéricos de archivos:

Definición de sistema de archivos
Un sistema de archivos (filesystem en la literatura) es un sistema de software (un conjunto de convenciones de denominación, almacenamiento y acceso) que permite almacenar y recuperar información en algún medio. Esta definición, muy general, se refiere a todos los programas que permiten que una computadora almacene información (cintas, discos flexibles, discos rígidos, memoria RAM) de tal modo que esa información se puede recuperar a voluntad del usuario. El sistema se encarga de mantener un directorio formado por bloques de información a los que se conoce con el nombre de archivos. Estos archivos poseen un nombre y suelen organizarse en directorios, que son el equivalente de carpetas en las cuales se pueden almacenar otros archivos o directorios. Se dice entonces que los sistemas de archivos tienen una estructura arborescente, con una "raíz" que es el directorio de entrada al sistema y (posiblemente) múltiples ramificaciones que podrán ser, a su vez, archivos o directorios. Los sistemas de archivos dependen del sistema operativo empleado; no es infrecuente hallar sistemas operativos que admiten múltiples sistemas de archivos.

Archivos de texto
Los ficheros de este tipo se utilizan fundamentalmente:
Caja de Pandora

    Retomando el tema del formato, del que hablábamos más arriba, los archivos de texto requieren especial cuidado a la hora de escribir y leer. Los lectores humanos tienen capacidades contextuales pero los ordenadores se atienen exclusivamente a la información textual. Por tanto, se emplean formatos de archivo como los que se describen a continuación. Utilizaremos como ejemplo el volcado a disco de una colección de estructuras como la siguiente:
struct Registro {
	char modelo[10];
	int fecha;
	char fabricante[20];
	float peso;
};



Véase a continuación un ejemplo de los tres formatos mencionados:

/*Formato encolumnado*/
 1271972SEAT1100.0
 1241968SEAT 855.0
 8501966SEAT 670.0
15001963SEAT 900.0
/*Formato delimitado por asteriscos*/
127*1972*SEAT*1100.000000
124*1968*SEAT*855.000000
850*1966*SEAT*670.000000
1500*1963*SEAT*900.000000
/*Formato de un campo por línea*/
127
1972
SEAT
1100.000000
124
1968
SEAT
855.000000
850
1966
SEAT
670.000000
1500
1963
SEAT
900.000000



Formato binario
Si se elimina la restricción propia de los archivos de texto, que sólo admiten caracteres imprimibles, es posible construir archivos que contengan cualquier byte. En este sentido hay que precisar que a efectos de los archivos, el formato binario y el formato de texto son una misma cosa. En un archivo se puede leer con formato o sin él, y se puede escribir con formato o sin él, pero el archivo, en sí, no implica transformación. Son las sentencias empleadas las que causan uno u otro formato.
El formato "binario", más general, se emplea en las siguientes ocasiones:

Por estas razones, el almacenamiento de datos numéricos de todo tipo (tablas, sonido, video) se hace siempre con este formato, en lugar de efectuar una traducción algún formato de texto.

Al igual que sucede con los formatos de texto, es imprescindible conocer el formato con que se escriben los ficheros binarios si se desea interpretar su contenido. En este sentido, es muy frecuente encontrar archivos de formato binario que contienen colecciones de estrucuras idénticas (registros). La lectura o escritura en estos archivos se hará normalmente en términos de estructuras del tipo empleado en su creación; el lenguaje mantiene, como se estudiará al describir la función fseek(), un "cursor" que señala el lugar en que se leerá o escribirá en la próxima operación. La posición del cursor es controlable por programa. De este modo, se puede leer o escribir cualquier registro deseado.
De forma similar a lo que ocurre en los archivos de texto, conviene dotar a los archivos binarios de un encabezado, que describe la organización de su contenido. Entonces el programa lee el encabezado, construye en memoria la oportuna estructura de datos, y después va trasladando el contenido del disco a memoria. Evidentemente, este encabezado es crucial para la interpretación del archivo, y por esta razón se suele duplicar al final del mismo. De este modo, cabe esperar que si se daña una de las copias la otra quede intacta y sea posible reconstruir el archivo, tarea que de otro modo será muy laboriosa. (Se puede incluir un marcador de fin de registro entre bloques de información, con objeto de facilitar la recuperación.)

¿Qué contiene un archivo binario?
La respuesta se puede obtener de manera sencilla mediante una herramienta como hexdump, que suele estar presente en todos los sistemas basados en Unix. Como ejemplo, vamos a considerar el archivo binario que genera el programa de base de datos estudiado en una sección anterior. Vamos a crear algunos registros, según se ve en la imagen, y después analizaremos el contenido del archivo binario asociado a esta pareja de registros. La imagen a que nos referimos es la siguiente:



Como puede verse, la base de datos contiene cuatro registros, que se almacenan en archivo.dat.



El resultado de aplicar hexdump a archivo.dat es el siguiente:



A primera vista (columnas de la izquierda) el resultado es un galimatías sin sentido. Pero la columna de la derecha permite apreciar fácilmente los nombres y apellidos, así como los teléfonos. Se puede apreciar que el código hexadecimal correspondiente al número 1 es el 31, y por tanto los códigos hexadecimales 32 y 33 corresponden a 2 y 3 respectivamente. La edad, sin embargo, resulta menos comprensible. Esto se debe a que se trata de un int, y como tal está codificado en formato binario, ocupando 4 bytes.

Como ejercicio, se sugiere al lector cambiar la posición de los campos, de modo que el nombre sea el primer campo y el apellido sea el último. Luego puede resultar instructivo insertar nombres y apellidos formados por una serie como AAAA...A y ZZZZ..Z. ¿Se aprecia ahora mejor el principio y el final de los campos? ¿Se aprecia la presencia del número 0 (el carácter '\0') al final de las cadenas? El ejemplo mostrado en la imagen permite ver esto claramente: en verdad, el formato interno de las cadenas en C tiene un marcador 0 al final.

Lectura por bloques y velocidad de transmisión.
Este es un problema interesante, que puede suponer notables ganancias de rendimiento si se emplean los métodos adecuados. Como se recordará, el tiempo requerido para acceder a la información residente en un disco es la suma de dos factores:
La cantidad de tiempo que se tarda en cargar una información en memoria depende del número de accesos a disco que es preciso realizar. Evidentemente, cuanto mayor sea el número de veces que se acceda a disco, mayor será el tiempo invertido. Es complicado conocer a priori el número real de accesos a disco necesarios, porque los subsistemas de disco hacen uso de un búfer en que se cargan múltiples bloques por acceso (al margen de lo solicitado), y lo mismo ocurre en el ordenador, pues el sistema operativo también hace uso de espacios de memoria intermedia par reducir el número de accesos. Por esta razón, suele ser muy rápido acceder a pequeños bloques de memoria, que residirán en el búfer del disco y también en el búfer del ordenador. Cuando se desborda la capacidad de estas memorias intermedias, cae el rendimiento, tanto en lectura como en escritura. En estas circunstancias aparece el "verdadero" comportamiento del disco, y la velocidad de acceso es tanto mayor cuando menor sea el número de accesos. Dicho de otro modo, se obtienen mejores velocidades cuanto mayor es el tamaño del bloque. Téngase en cuenta que, si el archivo no está fragmentado, una vez situadas las cabezas sólo queda esperar que la información vaya pasando por debajo de ellas, luego se obtiene velocidades de transferencia similares al máximo teórico. Cuanto mayor sea la fragmentación, desde luego, peor será el rendimiento, pues incurriremos en los costes de acceso para cada fragmento del archivo, irremediablemente.