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

From Free Pascal wiki
Jump to navigationJump to search
 
Line 4: Line 4:
  
 
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.
 
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 ([[End_of_Line|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:
 +
 +
<syntaxhighlight>...
 +
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.
 +
</syntaxhighlight>
 +
 +
=== Manejo de errores de Entrada/Salida ===
 +
The [http://www.freepascal.org/docs-html/prog/progsu38.html#x45-440001.2.38 I/O error handling flag] tells the compiler how to deal with error situations: raise an exception or store the I/O result in the IOResult variable.
 +
The I/O error handling flag is a compiler directive. To enable or disable it:
 +
<syntaxhighlight>{$I+} // Errors will lead to an EInOutError exception (default)
 +
{$I-} // Suppress I/O errors: check the IOResult variable for the error code
 +
</syntaxhighlight>
 +
 +
By suppressing I/O errors ({$I-}) the file operation results go into the IOResult variable. This is a [[Cardinal|cardinal (number) type]]. Different numbers mean different errors. So you may want to check the documentation for the different errors[http://www.freepascal.org/docs-html/rtl/system/ioresult.html].
 +
 +
===File procedures===
 +
These file handling procedures and functions are located in unit system. See the FPC documentation for more details: [http://www.freepascal.org/docs-html/rtl/system/index-5.html Reference for 'System' unit].
 +
 +
* '''AssignFile''' (prevent the use of the older '''Assign''' procedure) - Assign a name to a file
 +
* '''Append''' - Opens an existing file for appending data to end of file and editing it
 +
* '''BlockRead''' -  Read data from an untyped file into memory
 +
* '''BlockWrite''' - Write data from memory to an untyped file
 +
* '''CloseFile''' (prevent the use of the older '''Close''' procedure) - Close opened file
 +
* '''EOF''' - Check for end of file
 +
* '''Erase''' - Erase file from disk
 +
* '''FilePos''' - Get position in file
 +
* '''FileSize''' - Get size of file
 +
* '''Flush''' - Write file buffers to disk
 +
* '''IOResult''' - Return result of last file IO operation
 +
* '''Read''' - Read from a text file
 +
* '''ReadLn''' - Read from a text file and go to the next line
 +
* '''Reset''' - Opens a file for reading
 +
* '''Rewrite''' - Create a file for writing
 +
* '''Seek''' - Change position in file
 +
* '''SeekEOF''' - Set file position to end of file
 +
* '''SeekEOLn''' - Set file position to end of line
 +
* '''Truncate''' - Truncate the file at position
 +
* '''Write''' - Write variable to a file
 +
* '''WriteLn''' - Write variable to a text file and go to a new line
 +
 +
===Example===
 +
A full example of handling a text file of type TextFile:
 +
 +
<syntaxhighlight>program CreateFile;
 +
 +
uses
 +
Sysutils;
 +
 +
const
 +
  C_FNAME = 'textfile.txt';
 +
 +
var
 +
  tfOut: TextFile;
 +
 +
begin
 +
  // Set the name of the file that will be created
 +
  AssignFile(tfOut, C_FNAME);
 +
 +
  // Use exceptions to catch errors (this is the default so not absolutely requried)
 +
  {$I+}
 +
 +
  // Embed the file creation in a try/except block to handle errors gracefully
 +
  try
 +
    // Create the file, write some text and close it.
 +
    rewrite(tfOut);
 +
 +
    writeln(tfOut, 'Hello textfile!');
 +
    writeln(tfOut, 'The answer to life, the universe and everything: ', 42);
 +
 +
    CloseFile(tfOut);
 +
 +
  except
 +
    // If there was an error the reason can be found here
 +
    on E: EInOutError do
 +
      writeln('File handling error occurred. Details: ', E.ClassName, '/', E.Message);
 +
  end;
 +
 +
  // Give feedback and wait for key press
 +
  writeln('File ', C_FNAME, ' created if all went ok. Press Enter to stop.');
 +
  readln;
 +
end.</syntaxhighlight>
 +
 +
Now open the file in any text editor and you will see the above text written to it!
 +
You can test the error handling by running the program once, then set the file to read-only and run the program again.
 +
 +
Note that exception handling was used as that is an easy way to perfom multiple file operations and handling the errors. You could also use {$I-}, but then you would have to check IOResult after each operation and modify your next operation.
 +
 +
Here's how appending more text to a textfile works:
 +
<syntaxhighlight>program AppendToFile;
 +
 +
uses
 +
Sysutils;
 +
 +
const
 +
  C_FNAME = 'textfile.txt';
 +
 +
var
 +
  tfOut: TextFile;
 +
 +
begin
 +
  // Set the name of the file that will receive some more text
 +
  AssignFile(tfOut, C_FNAME);
 +
 +
  // Embed the file handling in a try/except block to handle errors gracefully
 +
  try
 +
    // Open the file for appending, write some more text to it and close it.
 +
    append(tfOut);
 +
 +
    writeln(tfOut, 'Hello again textfile!');
 +
    writeln(tfOut, 'The result of 6 * 7 = ', 6 * 7);
 +
 +
    CloseFile(tfOut);
 +
 +
  except
 +
    on E: EInOutError do
 +
    writeln('File handling error occurred. Details: ', E.Message);
 +
  end;
 +
 +
  // Give feedback and wait for key press
 +
  writeln('File ', C_FNAME, ' might have more text. Press enter to stop.');
 +
  readln;
 +
end.</syntaxhighlight>
 +
 +
Reading a textfile:
 +
 +
<syntaxhighlight>program ReadFile;
 +
 +
uses
 +
Sysutils;
 +
 +
const
 +
  C_FNAME = 'textfile.txt';
 +
 +
var
 +
  tfIn: TextFile;
 +
  s: string;
 +
 +
begin
 +
  // Give some feedback
 +
  writeln('Reading the contents of file: ', C_FNAME);
 +
  writeln('=========================================');
 +
 +
  // Set the name of the file that will be read
 +
  AssignFile(tfIn, C_FNAME);
 +
 +
  // Embed the file handling in a try/except block to handle errors gracefully
 +
  try
 +
    // Open the file for reading
 +
    reset(tfIn);
 +
 +
    // Keep reading lines until the end of the file is reached
 +
    while not eof(tfIn) do
 +
    begin
 +
      readln(tfIn, s);
 +
      writeln(s);
 +
    end;
 +
 +
    // Done so close the file
 +
    CloseFile(tfIn);
 +
 +
  except
 +
    on E: EInOutError do
 +
    writeln('File handling error occurred. Details: ', E.Message);
 +
  end;
 +
 +
  // Wait for the user to end the program
 +
  writeln('=========================================');
 +
  writeln('File ', C_FNAME, ' was probably read. Press enter to stop.');
 +
  readln;
 +
end.</syntaxhighlight>

Revision as of 17:31, 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

The I/O error handling flag tells the compiler how to deal with error situations: raise an exception or store the I/O result in the IOResult variable. The I/O error handling flag is a compiler directive. To enable or disable it:

{$I+} // Errors will lead to an EInOutError exception (default)
{$I-} // Suppress I/O errors: check the IOResult variable for the error code

By suppressing I/O errors ({$I-}) the file operation results go into the IOResult variable. This is a cardinal (number) type. Different numbers mean different errors. So you may want to check the documentation for the different errors[1].

File procedures

These file handling procedures and functions are located in unit system. See the FPC documentation for more details: Reference for 'System' unit.

  • AssignFile (prevent the use of the older Assign procedure) - Assign a name to a file
  • Append - Opens an existing file for appending data to end of file and editing it
  • BlockRead - Read data from an untyped file into memory
  • BlockWrite - Write data from memory to an untyped file
  • CloseFile (prevent the use of the older Close procedure) - Close opened file
  • EOF - Check for end of file
  • Erase - Erase file from disk
  • FilePos - Get position in file
  • FileSize - Get size of file
  • Flush - Write file buffers to disk
  • IOResult - Return result of last file IO operation
  • Read - Read from a text file
  • ReadLn - Read from a text file and go to the next line
  • Reset - Opens a file for reading
  • Rewrite - Create a file for writing
  • Seek - Change position in file
  • SeekEOF - Set file position to end of file
  • SeekEOLn - Set file position to end of line
  • Truncate - Truncate the file at position
  • Write - Write variable to a file
  • WriteLn - Write variable to a text file and go to a new line

Example

A full example of handling a text file of type TextFile:

program CreateFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfOut: TextFile;

begin
  // Set the name of the file that will be created
  AssignFile(tfOut, C_FNAME);

  // Use exceptions to catch errors (this is the default so not absolutely requried)
  {$I+}

  // Embed the file creation in a try/except block to handle errors gracefully
  try
    // Create the file, write some text and close it.
    rewrite(tfOut);

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

    CloseFile(tfOut);

  except
    // If there was an error the reason can be found here
    on E: EInOutError do
      writeln('File handling error occurred. Details: ', E.ClassName, '/', E.Message);
  end;

  // Give feedback and wait for key press
  writeln('File ', C_FNAME, ' created if all went ok. Press Enter to stop.');
  readln;
end.

Now open the file in any text editor and you will see the above text written to it! You can test the error handling by running the program once, then set the file to read-only and run the program again.

Note that exception handling was used as that is an easy way to perfom multiple file operations and handling the errors. You could also use {$I-}, but then you would have to check IOResult after each operation and modify your next operation.

Here's how appending more text to a textfile works:

program AppendToFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfOut: TextFile;

begin
  // Set the name of the file that will receive some more text
  AssignFile(tfOut, C_FNAME);

  // Embed the file handling in a try/except block to handle errors gracefully
  try
    // Open the file for appending, write some more text to it and close it.
    append(tfOut);

    writeln(tfOut, 'Hello again textfile!');
    writeln(tfOut, 'The result of 6 * 7 = ', 6 * 7);

    CloseFile(tfOut);

  except
    on E: EInOutError do
     writeln('File handling error occurred. Details: ', E.Message);
  end;

  // Give feedback and wait for key press
  writeln('File ', C_FNAME, ' might have more text. Press enter to stop.');
  readln;
end.

Reading a textfile:

program ReadFile;

uses
 Sysutils;

const
  C_FNAME = 'textfile.txt';

var
  tfIn: TextFile;
  s: string;

begin
  // Give some feedback
  writeln('Reading the contents of file: ', C_FNAME);
  writeln('=========================================');

  // Set the name of the file that will be read
  AssignFile(tfIn, C_FNAME);

  // Embed the file handling in a try/except block to handle errors gracefully
  try
    // Open the file for reading
    reset(tfIn);

    // Keep reading lines until the end of the file is reached
    while not eof(tfIn) do
    begin
      readln(tfIn, s);
      writeln(s);
    end;

    // Done so close the file
    CloseFile(tfIn);

  except
    on E: EInOutError do
     writeln('File handling error occurred. Details: ', E.Message);
  end;

  // Wait for the user to end the program
  writeln('=========================================');
  writeln('File ', C_FNAME, ' was probably read. Press enter to stop.');
  readln;
end.