Programación en Ada/Unidades predefinidas/Ada.Sequential IO
Ada.Sequential_IO es un paquete predefinido de la biblioteca estándar para el manejo de entrada y salida de ficheros secuenciales, esto es, ficheros en los que se leen o escriben los datos uno detrás de otro.
Instanciación
editarPara ser usado, el paquete Ada.Sequential_IO debe ser instanciado con el tipo a usar, es decir se debe especificar qué elemento debe leer/escribir: un entero, un carácter, un booleano, o un tipo definido por nosotros.
Para ello, usaremos la cláusula with. A continuación procedemos a instanciar el paquete de la siguiente forma
package
Nombreis
new
Ada.Sequential_IO(Tipo);
Ahora podremos usar la cláusula use.
use
Nombre
O bien ponerlo como prefijo a todas las operaciones y tipos de Ada.Sequential_IO
Nombre.Open(F,Nombre.In_file,"archivo.dat");
Si se hacen varias instanciaciones de Ada.Sequential_IO a diferentes tipos, será necesario usar el nombre del paquete que hemos puesto como prefijo
package
Pkg_integeris
new
Ada.Sequential_IO(Integer)package
Pkg_characteris
new
Ada.Sequential_IO(Character);; F: Pkg_integer.File_type; G: Pkg_character.File_type;
Funciones y procedimientos más comunes
editar- Open(F,Modo,Ruta)
- Permite abrir un fichero. Si el fichero no existe, devuelve una excepción 'Name_error'. 'F' es una variable File_type, 'Ruta' es la ruta del sistema donde se localiza el fichero y 'Modo' especifica como abrir el fichero: 'In_file' significa lectura, 'Out_file' significa escritura (borrando lo anterior) y 'Append_file' significa escritura empezando desde el final. Para acceder a este archivo, lo haremos a través de la variable File_type 'F'.
- Create(F,Modo,Ruta)
- Crea un fichero en la ruta del sistema elegida. Si no existe, se crea, y si existe, se sobreescribe. Los parámetros son los mismos que en 'Open', pero por defecto el modo es 'Out_file' (si creas un archivo, suele ser para escribir en él). Para acceder a este archivo, lo haremos a través de la variable File_type 'F'.
- Close(F)
- Cierra el archivo referido por la variable 'F'. Es necesario hacer esto cuando dejemos de leer o escribir en un fichero.
- Read(F,X)
- Lee de un fichero una variable 'X' del tipo instanciado, siendo F una variable File_type . Para leer se debe haber hecho un 'Open' previamente.
- Write(F,X)
- Escribe en un fichero una variable 'X' del tipo instanciado, siendo siendo F una variable File_type. Para escribir se debe haber hecho un 'Open' en modo escritura o un 'Create' previamente.
- End_of_file(F)
- Esta función devuelve 'True' (boolean) si hemos llegado al final del fichero y 'False' si quedan elementos por leer. Es importante saber usar esta función, ya que si intentamos leer un elemento del fichero habiendo llegado al final de éste, saltará la excepción 'End_Error'.
- Reset(F)
- Reinicia el cursor; para saber que elemento estamos leyendo, se guarda un cursor con la posición del elemento actual; esta operación lo reinicia, como si cerrásemos el fichero y lo volviésemos a abrir.
La lista completa de operaciones de Ada.Sequential_IO, se encuentra en el manual de referencia: A.8.1 The Package Sequential_IO.
Excepciones más frecuentes
editarEstas son algunas de las excepciones que pueden aparecer:
- End_Error: Hemos intentado leer un fichero cuando éste estaba vacío o si hemos llegado al final de él. Para prevenirlo, hay que usar la función End_of_file
- Name_Error: La ruta con la que hemos abierto un fichero es incorrecta, y el archivo no existe.
- Use_Error: Se suele dar cuando el archivo al que intentamos acceder ya está abierto por otro programa, o hemos hecho dos Open de un mismo archivo sin cerrar el primero. Para el primer caso, poco podemos hacer (es un programa externo el que influye) excepto avisar al usuario de que lo cierre; en el segundo caso el error es de código, ya que no hemos cerrado el fichero con un Close.
Ejemplos
editarwith
Ada.Text_IO, Ada.Sequential_IO;-- Ejemplo sencillo de uso Ada.Sequential_IO;
-- Copiamos un archivo para hacer una copia de seguridad
procedure
Copiadoris
type
Byteis
mod
2**8;package
Pkg_Byteis
new
Ada.Sequential_Io(Byte); C : Character := Ascii.Nul; B : Byte; Archivo_Original, Archivo_Copia : Pkg_Byte.File_Type; Ruta_Entrada : String (1 .. 32); Long_Ent : Integer := 0;begin
Ada.Text_Io.Put_Line("Introduzca el nombre del fichero de a copiar (maximo 32 caracteres)"
); Ada.Text_Io.Get_Line(Ruta_Entrada,Long_Ent);-- Abrimos el fichero en modo In_file, modo lectura,
-- con la ruta especificada por el usuario
Pkg_Byte.Open(Archivo_Original,Pkg_Byte.In_File,Ruta_Entrada(1..Long_Ent));-- Creamos un fichero del mismo nombre con terminación '.backup'
Pkg_Byte.Create(Archivo_Copia,Pkg_Byte.Out_File,Ruta_Entrada(1..Long_Ent) &".backup"
);-- Copiamos el contenido del fichero original al recién creado
-- Nótese el uso de End_of_file para prevenir la lectura de final de fichero
while
not
Pkg_Byte.End_Of_File(Archivo_Original)loop
Pkg_Byte.Read(Archivo_Original,B); Pkg_Byte.Write(Archivo_Copia,B);end
loop
;-- Importante: ¡No hay que olvidarse de cerrar los ficheros cuando no los usemos!
Pkg_Byte.Close(Archivo_Original); Pkg_Byte.Close(Archivo_Copia); Ada.Text_Io.Put_Line("Operacion realizada con exito"
); Ada.Text_Io.Put_Line("Presione cualquier tecla para finalizar"
); Ada.Text_Io.Get_Immediate(C);exception
when
Pkg_Byte.Name_Error=> Ada.Text_Io.Put_Line("Error: Nombre de archivo o ruta incorrectos"
);when
Pkg_Byte.Use_Error=> Ada.Text_Io.Put_Line("Error: El archivo ya esta abierto"
);end
Copiador;
with
Ada.Text_IO, Ada.Integer_Text_IO, Ada.Sequential_IO;-- Ejemplo avanzado de uso Ada.Sequential_IO;
-- Programa de 'cifrado' César
-- Leemos de un fichero, hacemos un desplazamiento mediante
-- una contraseña (método César) y escribimos en otro fichero.
-- Evidentemente la seguridad es casi nula, basta ir probando las
-- 255 posibilidades para sacarlo. Y si cifras dos veces consecutivas
-- de forma que sumen 256 también se saca.
procedure
Cesaris
type
Byteis
mod
2**8;package
Pkg_Byteis
new
Ada.Sequential_Io(Byte); C : Character := Ascii.Nul; B : Byte; Archivo_Entrada, Archivo_Salida : Pkg_Byte.File_Type; Ruta_Entrada, Ruta_Salida : String (1 .. 32); Password, Long_Ent, Long_Sal, Aux : Integer := 0;begin
while
C/='c'and
C/='d'loop
Ada.Text_Io.Put_Line("Cifrar (c) o Descifrar (d)?"
); Ada.Text_Io.Get_Immediate (C);if
C/='c'and
C/='d'then
Ada.Text_Io.New_Line; Ada.Text_Io.Put_Line("Error:Pulse la C o la D"
);end
if
;end
loop
; Ada.Text_Io.Put("Ha elegido: "
);if
C='c'then
Ada.Text_Io.Put("Cifrar"
); Ada.Text_Io.New_Line(2);else
Ada.Text_Io.Put("Descifrar"
); Ada.Text_Io.New_Line(2);end
if
; Ada.Text_Io.Put_Line("Introduzca el nombre del fichero de entrada (maximo 32 caracteres)"
); Ada.Text_Io.Get_Line(Ruta_Entrada,Long_Ent); Pkg_Byte.Open(Archivo_Entrada,Pkg_Byte.In_File,Ruta_Entrada(1..Long_Ent)); Ada.Text_Io.Put_Line("Introduzca el nombre del fichero de salida (maximo 32 caracteres)"
); Ada.Text_Io.Put_Line("Ojo, sobreescribira el fichero sin preguntar!"
); Ada.Text_Io.Get_Line(Ruta_Salida,Long_Sal); Pkg_Byte.Create(Archivo_Salida,Pkg_Byte.Out_File,Ruta_Salida(1..Long_Sal));while
Password<1or
Password>255loop
Ada.Text_Io.Put_Line("Elija un password (numero del 1 al 255)"
); Ada.Integer_Text_Io.Get(Password);if
Password<1or
Password>255then
Ada.Text_Io.New_Line; Ada.Text_Io.Put_Line("Error: El valor no es correcto. Debe estar entre 1 y 255"
);end
if
;end
loop
;while
not
Pkg_Byte.End_Of_File(Archivo_Entrada)loop
Pkg_Byte.Read(Archivo_Entrada,B);if
C='c'then
Aux:=(Integer(B)+Password) mod 256;else
Aux:=(Integer(B)-Password) mod 256;end
if
; Pkg_Byte.Write(Archivo_Salida,Byte(Aux));end
loop
; Pkg_Byte.Close(Archivo_Entrada); Pkg_Byte.Close(Archivo_Salida); Ada.Text_Io.Put_Line("Operacion realizada con exito"
); Ada.Text_Io.Put_Line("Presione cualquier tecla para finalizar"
); Ada.Text_Io.Get_Immediate(C);exception
when
Pkg_Byte.Name_Error=> Ada.Text_Io.Put_Line("Error: Nombre de archivo o ruta incorrectos"
);when
Pkg_Byte.Use_Error=> Ada.Text_Io.Put_Line("Error: El archivo ya esta abierto"
);when
Ada.Integer_Text_IO.Data_Error=> Ada.Text_Io.Put_Line("Error: La contraseña debe estar entre 1 y 255"
);end
Cesar;