Manejo de archivos
13. Acceso Aleatorio.
13.2. Archivos binarios
¿Por qué utilizar archivos binarios para acceso aleatorio?
Cuando trabajamos con archivos secuenciales, los datos se leen desde el comienzo hasta llegar a la información buscada.
Por ejemplo, si deseamos leer el registro número 100 de un archivo de texto, generalmente debemos leer los 99 registros anteriores para llegar a él.
Sin embargo, en muchas aplicaciones necesitamos acceder directamente a un registro específico sin recorrer todo el archivo. A esta técnica se la denomina acceso aleatorio o acceso directo.
Para lograrlo, el sistema debe poder calcular la posición exacta donde comienza cada registro dentro del archivo, vimos una plantilla que permitía ubicar datos entre etiquetas, esto favorece el cálculo de la ubicación.
Supongamos una estructura:
struct Persona {
int legajo; //4 bytes
char nombre[30]; //30 bytes
};
Si cada registro ocupa siempre la misma cantidad de bytes, podemos calcular fácilmente la ubicación de cualquier registro:
Registro 0 o instancia 0-> byte 0
Registro 1 o instancia 1 -> byte 34
Registro 2 o instancia 2 -> byte 68
Registro 3 o instancia 3 -> byte 102
...
Basta multiplicar:
nro_registro * sizeof(Persona)
para obtener la posición del registro deseado.
Luego podemos movernos directamente a esa posición mediante:
seekg()// para leer
seekp() //para escribir
sin necesidad de leer los registros anteriores.
¿Qué ocurre con los archivos de texto?
Supongamos el siguiente archivo:
Juan
Alejandro
Ana
Pedro
Cada línea posee una longitud diferente. , por lo tanto:
Juan -> 4 caracteres
Alejandro -> 9 caracteres
Ana -> 3 caracteres
Pedro -> 5 caracteres
No existe una fórmula simple que permita calcular dónde comienza una línea determinada.
Para llegar a la tercera línea es necesario leer las anteriores, podríamos pensar que facilita identificar los fines de línea, pero si hubieran eran varios campos en cada línea, deberíamos recorre toda la línea para ubicar el dato
Por esta razón los archivos de texto son ideales para acceso secuencial, pero no para acceso directo a registros.
¿Por qué abrir incluso archivos de texto en modo binario?
Cuando utilizamos funciones como:
seekg()
seekp()
tellg()
tellp()
trabajamos con posiciones expresadas en caracteres, o lo que es lo mismo bytes, por que un byte es el tamaño de un caracter. En modo texto, algunos sistemas operativos realizan conversiones automáticas de caracteres. Por ejemplo, el fin de línea puede almacenarse físicamente como:
\r\n //retorno de carro y nueva línea
aunque el programa lo interprete como:
\n //nueva línea
Estas conversiones dificultan que exista una correspondencia exacta entre posición lógica y posición física dentro del archivo.
En cambio, cuando el archivo se abre en modo binario:
ios::binary
cada byte del archivo se maneja exactamente como está almacenado.
De esta manera:
seekg()
seekp()
tellg()
tellp()
Lo métodos trabajan sobre posiciones reales y predecibles refiriéndose a caracteres en archivos de texto y a bytes en archivos binarios.
Idea fundamental
El acceso aleatorio necesita conocer posiciones exactas dentro del archivo.
Por esta razón suele utilizarse:
-
Registros de tamaño fijo.
-
Archivos binarios.
-
Posicionamiento mediante bytes.
De esta forma es posible acceder directamente a cualquier registro sin recorrer los anteriores.
Vamos a ver esto a continuación.