Difference between revisions of "File Handling In Pascal/es"

From Free Pascal wiki
Jump to navigationJump to search
Line 191: Line 191:
 
   // Espera la intervención del usuario para finalizar el programa.
 
   // Espera la intervención del usuario para finalizar el programa.
 
   writeln('=========================================');
 
   writeln('=========================================');
   writeln('fichero ', C_FNAME, ' fue probablemente leido. Presion Enter para finalizar.');
+
   writeln('fichero ', C_FNAME, ' fue probablemente leido. Presiona Enter para finalizar.');
 
   readln;
 
   readln;
 
end.</syntaxhighlight>
 
end.</syntaxhighlight>

Revision as of 18:26, 24 June 2015

العربية (ar) English (en) español (es) suomi (fi) français (fr) 日本語 (ja) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

Descripción

Algo que necesitan conocer todos los programadores es como trabajar con ficheros. Los ficheros se utilizan para almacenar datos de forma persistente, i.e. almacenar datos de manera que puedan ser retornados en un momento posterior sin tener que volver a crearlos. Los ficheros pueden utilizarse para almacenar configuraciones de usuario, reportes de error, medidas o resultados de cálculos, etc. Esta página explica lo básico sobre manejo de ficheros.

Estilo del procedimiento antiguo

Cuando se utilizan ficheros en el modo clásico de Pascal (no orientado a objetos) se puede utilizar el tipo 'TextFile' (o simplemente 'Text') para almacenar texto, que está estructurado típicamente en líneas. Cada línea finaliza con una marca de fin de línea (EOL=End Of Line). En este tipo de fichero se pueden almacenar tanto cadenas (strings) como números (integer, real...) formateados además de la forma que más nos convenga. Estos ficheros pueden posteriormente abrirse para visualizarlos o editarlos mismamente con el IDE de Lazarus o cualquier otro editor de texto.

Para propósitos específicos se puede crear un tipo de fichero personalizado que puede almacenar únicamente un tipo de dato. Por ejemplo:

...
type
  TIntegerFile  = file of integer;  // Permite escribir únicamete números de tipo entero (integer) al fichero.
  TExtendedFile = file of extended; // Permite escribir úncamente números de tipo real al fichero.
  TCharFile     = file of char;     // Permite escribir únicamente caracteres simples al fichero.

Manejo de errores de Entrada/Salida

El I/O error handling flag o flag (bandera) de Entrada/Salida (I/O -> Input/Output) indica al compilador como manejarse con las situaciones de error: lanzar una excepción o almacenar el resultado de la entrada/salida en la variable IOResult.

El flag de manejo del error de entrada/salida es una directiva del compilador. Para habilitarlo/deshabilitarlo escribimos:

{$I+} // Los errores generarán una excepción EInOutError (por defecto)
{$I-} // Suprime los errores de entrada/salida: chequea la veriable IOResult para saber su código de error.

Mediante la supresión de los errores de entrada/salida utilizando ({$I-}) los resultados de la operación con ficheros se meterán en la variable IOSResult. Este es un cardinal (number) type. Cada uno de los distintos numeros indicarán los diferentes errores obtenidos. Estos códigos de error se pueden consultar en la documentación [1].

Procedimientos de fichero

Estas funciones y procedimientos de manejo de ficheros se encuentran en la unit 'system'. Ver la documentación de FPC para más detalles:

Referenccia sobre la unidad 'System'.

  • AssignFile (previene del uso del antiguo procedimiento Assign ) - Asigna un nombre a un fichero.
  • Append - Abre un fichero ya existente en el modo añadir al final del mismo.
  • BlockRead - Lee un bloque de datos de un fichero sin tipo poniéndolo en memoria.
  • BlockWrite - Escribe un bloque de datos desde la memoria hacia un fichero sin tipo.
  • CloseFile (previene el uso del procedimiento antiguo Close ) - Cierra un fichero que está abierto.
  • EOF - Chequea si se ha llegado al final del fichero (EOF=End Of File), devuelve true si ha llegado y false si todavía no.
  • Erase - Borra un fiechro del disco.
  • FilePos - Retorna da la posición en que nos encontramos dentro del fichero.
  • FileSize - Retorna el tamaño del fichero.
  • Flush - Escribe los buffers de fichero a disco.
  • IOResult - Retorna el resultado de la última operación de entrada/salida (I/O) de ficheros.
  • Read - Lee desde un fichero tipo texto.
  • ReadLn - Lee desde un fichero tipo texto (una línea entera) y salta a la siguiente línea.
  • Reset - Abre un fichero para lectura.
  • Rewrite - Crea un fichero para escritura.
  • Seek - Cambia a una posición dentro del fichero.
  • SeekEOF - Sitúa la posición dentro del fichero en su final.
  • SeekEOLn - sitúa la posición del fichero al final de la línea.
  • Truncate - Trunca el fichero en la posición indicada.
  • Write - Escribe una variable en el fichero.
  • WriteLn - Escribe una variable a un fichero de texto y salta a una nueva línea.

Ejemplo

Un ejemplo completo de manejo de un fichero de texto del tipo 'TextFile':


program CreateFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfOut: TextFile;

begin
  // Establece el nombre del fichero que vamos a crear
  AssignFile(tfOut, C_FNAME);

  // Habilitamos el uso de excepciones para interceptar los errores (esto es como está por defecto por lo tanto no es absolutamente requerido)

  {$I+}

  // Embebe la creación del fichero en un bloque try/except para manejar los errores elegántemente.
  
  try
  
    //crea el fichero, escribe algo de texto y lo cierra.
    rewrite(tfOut);

    writeln(tfOut, 'Hello textfile!');
    writeln(tfOut, 'The answer to life, the universe and everything: ', 42);

    CloseFile(tfOut);

  except
    // Si ocurre algún error podemos encontrar la razón en E: EInOutError 
      writeln('Ha ocurrido un error en el manejo del fichero. Detalles: ', E.ClassName, '/', E.Message);
  end;

  // Da información y espera por la pulsación de una tecla.
  writeln('Fichero ', C_FNAME, ' creado si todo fue bien. Presiona Enter para finalizar.');
  readln;
end.

Ahora abre el fichero generado utilizando para ello cualquier editor y verás justamente el texto que hemos escrito mediante código. Puedes probar el manejo de errores ejecutando el programa de nuevo, en esta ocasión la prueba que puedes realizar es establecer el atributo del fichero en modo solo lectura de forma que el programa no pueda hacer el rewrite y ver el error que nos lanza. Now open the file in any text editor and you will see the above text written to it!

Nota que el manejo de excepciones se ha utilizado como una manera fácil de realizar múltiples operaciones con ficheros y manejar los errores que obtengamos como resultado. También puedes utilizar {$I-}, pero en este caso hay que consultar el valor almacenado en la variable IOResult después de cada operación y modificar tu próxima operación para tratar el posible error.

Lo siguiente muestra como se puede añadir texto a un fichero del tipo textfile (al final del contenido ya existente):

program AppendToFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfOut: TextFile;

begin
  // Establece el nombre del fichero que va a recibir más texto.
  AssignFile(tfOut, C_FNAME);

  // Embebe el manejo del fichero en un bloque try/except para gestionar los errores de manera elegante.
  try
    // Abre el fichero en la modalidad añadir (appending), escrie algo de texto y lo cierra.
    append(tfOut);

    writeln(tfOut, ' Hola de nuevo fichero de texto. ');
    writeln(tfOut, 'El resultado de 6 * 7 = ', 6 * 7);

    CloseFile(tfOut);

  except
    on E: EInOutError do
     writeln('Ha ocurrido un error en el manejo del fichero. Detalles: ', E.Message);
  end;

  // Da información y espera a que se pulse una tecla.
  writeln('Fichero ', C_FNAME, ' puede contener más texto. Presiona Enter para finalizar.');
  readln;
end.

Leyendo un fichero de texto (textfile):

program ReadFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfIn: TextFile;
  s: string;

begin
  // Da algo de información
  writeln('Leyendo el contenido del fichero: ', C_FNAME);
  writeln('=========================================');

  // Establece el nombre del fichero a leer.
  AssignFile(tfIn, C_FNAME);

  // Embebe el manejo del fichero en un bloque try/except para manejar errores de manera elegante.
 try
    // Abre el fichero en la modalidad de lectura.
    reset(tfIn);

    // Se mantiene leyendo líneas hasta alcanzar el final del fichero.
    while not eof(tfIn) do  // Mientras no fin de fichero haz...
    begin
      readln(tfIn, s); // Lee una línea de texto desde el fichero.
      writeln(s);  // Escribe la línea de texto leida anteriormente mostrándola en pantalla.
    end;

    // Realizado, por tanto prcedemos a cerrar el fichero.
    CloseFile(tfIn);

  except
    on E: EInOutError do
     writeln('Ha ocurrido un error en el manejo del fichero. Detalles: ', E.Message);
  end;

  // Espera la intervención del usuario para finalizar el programa.
  writeln('=========================================');
  writeln('fichero ', C_FNAME, ' fue probablemente leido. Presiona Enter para finalizar.');
  readln;
end.