Los ficheros surgen de la
necesidad de almacenar información una vez que termina el programa y poder
usarla en ejecuciones futuras de ese mismo programa o de otros.
Es el único mecanismo que
tenemos para guardar información cuando nos quedamos sin suministro eléctrico y
poder recuperarla después.
El acceder a la información de
los ficheros supone acceder a dispositivos que al lado de la memoria de un
ordenador resultan excesivamente lentos, ya que supone el desplazamiento
mecánico de cabezas lectoras y eso supone un retraso importante en el acceso a
la información.
Ficheros secuenciales
Almacenan una secuencia de
datos de cualquier tipo (pero todos del mismo tipo). Por ejemplo, puedo tener
un fichero que almacena una secuencia de enteros, de reales, de vectores de lo
que sea, de registros de cualquier tipo, etc.
No los podemos editar con un
editor de textos (o bueno, podemos pero no vamos a entender nada).
Para crearlos, acceder a la
información, o modificarlos lo habitual es hacerlo por programa.
Ficheros de texto
Almacenan únicamente
caracteres codificados en ASCII.
Por consiguiente, para acceder
a la información o modificarlos, podría hacer uso indistintamente de un programa
o un editor de textos (aunque desde el editor tendré problemas con los
caracteres no representables).
Si nos damos cuenta, tanto el
uno como el otro son exactamente lo mismo (muchos bytes uno detrás de otro).
Por lo tanto, lo único que varía entre un fichero secuencial binario y uno de
texto, es su contenido lógico. Un fichero sea del tipo que sea podemos luego
interpretarlo como queramos. Es decir, ¿puedo coger un fichero secuencial que
contiene datos del tipo que sea y abrirlo como si fuera un fichero de texto, y
viceversa?
Bueno, con ciertas
matizaciones, por ejemplo, que el número de bytes que contiene sea múltiplo del
tipo de fichero secuencial, s es de texto y resulta incomprensible.
Cuando me refiero a un
fichero, la palabra secuencial tiene que ver con el tipo de acceso a la
información de que dispongo, en este caso, un acceso secuencial.
Un fichero secuencial de datos
de tipo “tpDato” es una estructura de datos cuyo dominio de valores son las
secuencias finitas de datos del tipo “tpDato”, con un conjunto restringido de
operadores, que fundamentalmente permiten sólo el acceso secuencial a sus
componentes.
Lo que significa y supone el
acceso secuencial es que, en un momento dado, sólo puede accederse de forma
inmediata a uno de los componentes del fichero, y para acceder a un elemento es
preciso haber accedido antes a todos los elementos anteriores.
Es decir, con un vector por
ejemplo, yo puedo acceder directamente a la componente 1000 del vector si es
justo el dato que necesito.
Con un fichero secuencial, si
yo quiero el dato 1000 tengo que acceder primero a los 999 anteriores. Por
tanto los accesos son mucho más lentos, debido a dos razones diferentes:
§ El dispositivo de almacenamiento es más
lento (los discos duros son más lentos que las memorias)
§ El acceso en el caso del fichero es
secuencial, mientras que en memoria el acceso es directo.
Es útil para guardar y
recuperar información, pero bastante inútil para buscar de manera eficiente
información en él.
§ iniciarEscritura(f): Procedimiento para la creación del fichero
como una secuencia vacía
§ escribir(f,expresión): Procedimiento para la adición (escritura)
de un dato al fichero f
§ iniciarLectura(f): Proceso para iniciar el proceso de
inspección
§ siguienteDato(f):
Función para consultar el
siguiente dato a acceder (sin avanzar a él). Muchos lenguajes no lo tienen
disponible
§ avanzar(f):
Procedimiento para avanzar
al siguiente dato almacenado en el fichero f. Se usa junto con siguienteDato(f)
y tampoco está definido en muchos lenguajes
§ leer(f,
variable): Procedimiento
para la lectura del siguiente dato almacenado en el fichero f. Lo lee, lo
guarda en la variable y avanza (siguienteDato + avanzar, todo en
uno).
§ finFichero(f):
Función para consultar si
se ha accedido al final del fichero f. Valdrá VERDAD cuándo se haya leído el
último dato de f.
§ asociar(f,
nombre): Establece la
conexión lógica entre un fichero interno (variable f en este caso, que
es la que utilizaremos en nuestro algoritmo) y el correspondiente fichero
externo (el fichero que tenga el nombre indicado, que es lo que quedará en el
sistema de ficheros cuándo nuestro programa termine). La sintaxis de este
nombre se ajustará a las reglas definidas por el S.O.
§ disociar(f): Deshace la conexión lógica entre la
variable del algoritmo y el fichero del nombre que se indicó, de tal manera que
la variable quede libre para poder ser utilizado sobre ese u otros ficheros, y
se garantiza que se han realizado todas las operaciones realmente sobre el
fichero (a veces, cuando escribimos sobre el fichero, no se fuerza su escritura
sobre el fichero real. Si no disociamos un fichero antes de terminar el
programa, podríamos no haber escrito realmente datos que hemos dado las
instrucciones para que se escriban).
Algoritmo crearFicherosEnteros
{Almacenar en un fichero “números.dat” los N números naturales. N es
obtenido de forma interactiva}
Tipos
tpFichero:=fichero de
entero;
variables
f:tpFichero;
N:entero {Máximo número
a almacenar};
contador:entero;
principio
escribirCadena(pantalla,”¿Números
a almacenar en el fichero?”);
leerEntero(teclado,N);
asociar(f,”numeros.dat”);
inciarEscritura(f);
contador:=1;
mientras que
contador<=N hacer
escribir(f,contador);
contador:=contador+1;
fmq;
disociar(f);
fin;
Algoritmo mostrarFicherosEnteros
{Visualizar los datos en un fichero “numeros.dat” de datos enteros}
Tipos
tpFichero:=fichero de
entero;
variables
f:tpFichero;
num:entero;
principio
asociar(f,”numeros.dat”);
iniciarLectura(f);
mientras que NOT
finFichero(f) hacer
leer(f,num);
escribirEntero(pantalla,Num);
fmq;
disociar(f);
fin
Algoritmo separarImpares
{Separa los números pares e impares del fichero “datos.dat”
guardándolos respesctivamente en los ficheros “pares.dat” e “impares.dat”}
Tipos
tpFichero:=fichero de
entero
variables
f, i, p:tpFichero;
dato:entero;
principio
asociar(f,”datos.dat”);
asociar(i,”impares.dat”);
asociar(p,”pares.dat”);
inciarLectura(f);
iniciarEscritura(i);
iniciarEscritura(p);
mientras que NOT
finFichero(f) hacer
leer(f,dato);
si dato MOD 2=0
entonces
escribir(p,Dato);
si no
escribir(i,Dato);
fsi
fmq
disociar(f);
disociar(i);
disociar(p);
fin
Los ficheros de texto son
simples ficheros secuenciales de caracteres. No obstante, dada la importancia
de su uso, los vemos en mayor profundidad de forma específica.
Funcionan a todos los efectos
como cualquier fichero secuencial de cualquier tipo de dato, aunque hay algunas
operaciones especiales pensadas específicamente para ellos.
Los lenguajes de programación
suelen tratarlos de un modo especial, incluso algunos traen predefinidos un
tipo fichero de texto.
Algoritmo contarVocales
{Cuenta el número de vocales que tiene un fichero de texto “a.txt”}
Variables
f:texto;
c:caracter;
contador:entero;
principio
asociar(f,”a.txt”);
iniciarLectura(f);
contador:=0;
mientras que NOT
finFichero hacer
leer(f,c);
si (c:=’A’ or
c:=’E’ or c:=’I’ or c:=’O’ or c:=’U’ or c:=’a’ or c:=’e’ or c:=’i’ or c:=’o’ or
c:=’u’)
entonces
contador:=contador+1;
fsi
fmq
escribirCadena(pantalla,”Número
de vocales”);
escribirEntero(pantalla,contador);
disociar(f);
fin
§ acabarLinea(f):
Procedimiento que da por
concluida la línea en curso en el fichero f cuándo estoy escribiendo en él
§ avanzarLinea(f):
Procedimiento que salta los
caracteres que pueden estar pendientes de ser leídos en la línea en curso del
fichero f y dispone al ordenador para leer el primer carácter de la siguiente
línea (cuando estoy leyendo del fichero).
§ finLinea(f):
Función que devuelve VERDAD
si ha terminado con todos los caracteres de la línea en curso y FALSO en caso
contrario Cuando acaba la línea pasará a la siguiente haciendo uso del
procedimiento avanzarLinea
...
asociar(f,”fichero.txt”);
iniciarEscritura(f);
mientras que “haya líneas que añadir” hacer
mientras que “haya
caracteres que añadir en la línea actual” hacer
“obtener el
caracter C”;
escribir(f,c);
fmq
acabarLinea(f);
fmq
disociar(f);
…
…
asociar(f,”fichero.txt”);
iniciarLectura(f);
mientras que NOT finFichero(f) hacer
mientras que NOT
finLinea(f) hacer
leer(f,c);
“tratar el caracter
c”;
fmq
avanzarLinea(f);
fmq
disociar(f);
…
0 comentarios:
Publicar un comentario