|
Los archivos o ficheros brindan una forma de guardar permanentemente los datos y resultados de nuestros programas.
Es importante indicar que los ficheros no son únicamente los archivos que guardamos en el disco duro. En QBasic algunos dispositivos del ordenador (como el puerto serie de comunicaciones) se tratan como ficheros.
Para comenzar, vamos a analizar un ejemplo que lee un fichero de texto (origen.txt) y muestra su contenido en la pantalla:
' Lee un archivo de texto línea a línea DIM linea AS STRING OPEN "origen.txt" FOR INPUT AS #1 ' Abre el archivo para lectura PRINT "Contenido del fichero:" DO WHILE NOT EOF(1) ' Comprueba si se ha alcanzado el fin del archivo LINE INPUT #1, linea ' Lee una línea del archivo (hasta RC/LF: salto de línea) PRINT linea LOOP CLOSE #1 ' Cierra el archivo END |
Analizaremos este ejemplo poco a poco deteniéndonos en:
y, posteriormente, nos referiremos a:
![]() |
Apertura del fichero para lectura: OPEN |
Ahora es preciso abrir el fichero. Para ello usamos la función OPEN. Esta sentencia tiene el siguiente formato:
OPEN nombre_archivo$ [FOR modo] AS [#]nº_archivo%
En el ejemplo usábamos:
OPEN "origen.txt" FOR INPUT AS #1
El nombre de fichero se puede indicar directamente (como en el ejemplo) o usando una variable y se puede abrir de diversas formas. Esto se especifica con el parámetro modo. Los modos posibles son:
INPUT |
especifica que el archivo
va a ser abierto para leer información de forma secuencial. |
OUTPUT |
especifica que el archivo va a ser abierto para escribir información de forma secuencial. |
RANDOM |
especifica que el archivo
va a ser abierto en el modo de acceso aleatorio. RANDOM es el modo de archivo predeterminado. |
APPEND |
especifica que el
archivo va a ser abierto para añadir información de salida
secuencial y coloca el puntero de archivo al final del archivo. Una
instrucción PRINT # o WRITE # añade la
información al archivo. |
BINARY |
especifica el modo de
archivo binario. En este modo, es posible leer o escribir información en cualquier posición de byte del archivo usando instrucciones GET o PUT. |
nº_archivo
es un identificador que permite distinguir los
distintos ficheros que se utilizan, cuando se usan varios simultáneamente.
![]() |
Lectura de caracteres del fichero: LINE INPUT # |
Ahora ya podemos empezar a leer el fichero. Para ello podemos utilizar la función LINE NPUT #, que lee las líneas de texto del archivo de una en una. Se puede usar también la función INPUT # que lee texto del archivo hasta que encuentra una coma (,).
El formato de la instrucción INPUT #
es:
[LINE] INPUT #nº_archivo, variable$
En este caso lo usamos como:
LINE INPUT #1, linea |
donde linea
es una variable string. Tomamos una línea de fichero,
la almacenamos en linea y el
puntero del fichero se coloca al principio de la línea siguiente.
![]() |
Comprobación de fin de fichero: EOF() |
Cuando entramos en el bucle WHILE, la lectura se realiza hasta que se encuentre el final del fichero. La detección del final del fichero se puede llevar a cabo con la función EOF().
Esta función es de la forma:
EOF(nº_archivo)
Esta función comprueba si se ha llegado al final de nº_archivo, en cuyo caso devuelve un valor verdadero (no 0). Si no se ha llegado al final de fichero devuelve falso (0). Por eso lo usamos del siguiente modo:
DO WHILE NOT EOF(1) |
o
DO UNTIL EOF(1) |
![]() |
Cierre del fichero: CLOSE |
Una vez realizadas todas las operaciones deseadas sobre el fichero hay que cerrarlo. Es importante no olvidar este paso pues el fichero podría corromperse. Al cerrarlo se vacían los buffers y se guarda el fichero en disco. Un fichero se cierra mediante la instrucción CLOSE. Esta función tiene el siguiente formato:
CLOSE [#]nº_archivo
Aquí nº_archivo es el identificador del archivo indicado en OPEN cuando el archivo se abrió:
CLOSE #1 |
CLOSE sin argumentos cierra todos los archivos abiertos.
![]() |
Lectura de caracteres del fichero: INPUT$() |
Esta función es muy útil para leer caracteres un nº de caracteres determinado del archivo. Su formato es:
INPUT(nº_caracteres, [#]nº_archivo)
Esta función lee desde el fichero nº_archivo el número de bytes especificado por nº_caracteres.
Por ejemplo, el siguiente programa muestra todo el contenido del fichero "origen.txt" byte a byte.
' Lee un archivo de texto carácter a carácter DIM letra AS STRING*1 OPEN "origen.txt" FOR INPUT AS #1 ' Abre el archivo para lectura PRINT "Contenido del fichero:" DO WHILE NOT EOF(1) ' Comprueba si se ha alcanzado el fin del archivo letra = INPUT$(1,1) ' Lee un carácter del archivo PRINT letra; LOOP CLOSE #1 ' Cierra el archivo END |
Vamos a completar ahora la parte que faltaba en la sección anterior: escribir en un fichero. Vamos a hacerlo de nuevo mediante un ejemplo. En éste, abrimos un fichero origen.txt y lo copiamos en otro destino.txt. Además, el fichero se muestra en pantalla (las partes nuevas se han destacado en negrita).
' Ejemplo de escritura de archivos DIM linea AS STRING OPEN "origen.txt" FOR INPUT AS #1 ' Abre el archivo origen para lectura OPEN "destino.txt" FOR OUTPUT AS #2 ' Abre el archivo destino para escritura DO WHILE NOT EOF(1) LINE INPUT #1, linea ' Lee una línea del archivo origen PRINT #2, linea ' Escribe la línea en el archivo destino PRINT linea ' Muestra contenido en pantalla LOOP CLOSE #1, #2 END |
Como en el caso de la lectura de archivos, analizaremos este ejemplo poco a poco deteniéndonos en:
![]() |
Apertura del fichero para escritura: OPEN |
El siguiente paso, como antes, es abrir el fichero usando OPEN. La diferencia es que ahora tenemos que abrirlo en modo escritura. Usamos el modo OUTPUT (crea el fichero, o lo vacía si existe) porque queremos crear un fichero:
OPEN "destino.txt" FOR OUTPUT AS #2
![]() |
Escritura de caracteres en el archivo: PRINT # |
Como se puede observar en el ejemplo, la lectura del fichero se hace igual que antes, con LINE INPUT #. Para la escritura usamos la función PRINT , cuya sintaxis es:
PRINT #nº_archivo, lista_expresioens
En este caso lo usamos como:
PRINT #2, linea |
De esta forma vamos escribiendo en el fichero destino.txt el contenido del fichero origen.txt.
Si hubiésemos escrito la anterior instrucción así:
PRINT #2, linea; |
(nótese el ; final) en el archivo destino.txt las líneas del archivo origen aparecerían concatenadas (es decir, no se producirían saltos de línea)
![]() |
Comprobación fin de fichero |
Como siempre que leemos datos de un fichero debemos comprobar si hemos llegado al final. Sólo debemos comprobar si estamos al final del fichero que leemos. No tenemos que comprobar el final del fichero en el que escribimos puesto que lo estamos creando y aún no tiene final.
![]() |
Cierre del fichero: CLOSE |
Y, por fin, lo que nunca debemos olvidar al trabajar con ficheros: cerrarlos. Debemos cerrar tanto los ficheros que leemos como aquellos sobre los que escribimos.
CLOSE #1, #2 |
Obsérvese que cerramos ambos archivos con una única instrucción.
![]() |
WRITE |
Esta sentencia es muy similar a PRINT #, de hecho, la sintaxis es idéntica:
WRITE #nº_archivo, lista_expresioens
Sin embargo, WRITE inserta comas (,) entre los datos y comillas (") alrededor de cadenas de texto. Para notar la diferencia considérese el siguiente ejemplo:
OPEN "destino.txt" FOR OUTPUT AS #1 PRINT #1, 1, 2, "Tecnología" WRITE #1, 1, 2, "Tecnología" CLOSE #1 |
Como resultado, en el archivo "destino.txt" se escribirá:
1
2 Tecnología
1,2,"Tecnología"
![]() |
GET y PUT |
GET lee información de un archivo colocándola en un buffer de acceso
aleatorio o en una variable.
PUT escribe una variable o un buffer de acceso aleatorio en un archivo.
La sintaxis es:
GET [#]numarchivo%[,[numregistro&][,variable]] PUT [#]numarchivo%[,[numregistro&][,variable]]
TYPE RegistroPrueba ' Define un tipo de datos con un texto de 20 caracteres y un número de precisión simple Alumno AS STRING * 20 Nota AS SINGLE END TYPE DIM MiClase AS RegistroPrueba ' Declara una variable edl tipo anterior OPEN "FINAL.DAT" FOR RANDOM AS #1 LEN = LEN(MiClase) MiClase.Alumno = "Pérez Ruiz" MiClase.Nota = 9 PUT #1, 1, MiClase CLOSE #1 OPEN "FINAL.DAT" FOR RANDOM AS #1 LEN = LEN(MiClase) GET #1, 1, MiClase PRINT "Estudiante:"; MiClase.Alumno PRINT "Nota:"; MiClase.Nota CLOSE #1 |
Este programa produce la salida:
Estudiante: Pérez Ruiz Nota: 9 |
![]() |
Posicionamiento en el fichero: LOC y SEEK |
Supongamos que queremos posicionarnos en un byte concreto de un archivo para leer o escribir en dicha posición. La función LOC devuelve la posición actual del puntero del archivo identificado por nº_archivo. Su sintaxis es:
LOC(nº_archivo%)
La instrucción SEEK establece la posición del archivo para la siguiente acción de lectura o escritura:
SEEK [#]nº_archivo%, posición&
- numarchivo% es el número de un archivo abierto.
- posición& es la posición donde ocurrirá la siguiente acción de leer o escribir. Para archivos de acceso aleatorio, un número de registro. Para otros archivos, la posición de byte con relación al principio del archivo. El primer byte ocupa la posición 1.
OPEN "prueba.txt" FOR RANDOM AS #1 FOR i% = 1 TO 10 PUT #1, , i% NEXT i% SEEK #1, 2 ' Se posiciona en el segundo registro GET #1, , i% ' Lee el registro donde se halla posicionado PRINT "Datos: "; i%; " Registro actual: "; LOC(1)
Este programa escribe secuencialmente 10 registros con los enteros entre 1 y 10, se posiciona en el segundo registro y lo lee; proporciona la salida:
Datos: 2 Registro actual: 2 |