BotonMenu
BotonIndice

Visita : http://www.conoce3000.com
Paypal : https://www.paypal.me/conoce3000/1

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL


9. ARCHIVOS.
9.4. ARCHIVOS CON TIPO. (RUTINAS TRADICIONALES O ESTÁNDAR)
9. ARCHIVOS.
9.4. ARCHIVOS CON TIPO. (RUTINAS TRADICIONALES O ESTÁNDAR)
9. ARCHIVOS.
9.4. ARCHIVOS CON TIPO. (RUTINAS TRADICIONALES O ESTÁNDAR)

SIGUIENTE

SIGUIENTE

SIGUIENTE


‒ Archivos con tipo. (Rutinas tradicionales o estándar)

Los archivos con tipo son archivos de acceso aleatorio, sólo se pueden asociar con dispositivos de almacenamiento u otro que permita el acceso aleatorio. Los archivos con tipo son como los arreglos, y se definen con la palabra reservada File seguido del tipo de dato que definirá cada bloque o elemento que tendrá el archivo. Para acceder a un determinado elemento o bloque de un archivo con tipo, se hace uso del puntero de archivo que se puede mover con el procedimiento seek. Los bloques o elementos de un archivo con tipo se enumeran empezando con 0. La cantidad de elementos o bloques que puede tener un archivo con tipo está limitado sólo con la cantidad de espacio con el que cuente un dispositivo de almacenamiento.

Los tipos de datos que se pueden usar con archivos con tipo son: Números enteros, Booleanos, Caracteres, Enumerados, Subrangos, Reales, Arreglos estáticos, Cadena de caracteres (String), Registros y Conjuntos. Los archivos con tipo se asocian con un flujo del mismo modo como se hace con los archivos de texto, es decir se usa el procedimiento assign, también se usan los procedimientos reset, rewrite y close. El procedimiento reset cambia su comportamiento cuando se usa con archivos con tipo, ya que este nos permite abrir el archivo, tanto para lectura como para escritura. Rewrite y close funcionan igual. El procedimiento append no se puede usar con archivos con tipo, y no es necesario ya que con el uso de reset y seek, se puede ir añadiendo más bloques o elementos al final de un archivo con tipo.

Al igual que los archivos de texto, en Windows los nombres de los archivos con tipo sólo deben estar en ASCII o una de sus variantes ANSI. Ejemplo:


Descargar
{$codepage utf8}
{$ifdef win32}
   Uses sysutils;
{$endif}
{$ifdef Unix}
   Uses sysutils,cwstring;
{$endif}
   Var Arch:File of integer;
       i:byte;
       b:integer;


Begin
   Assign(Arch,'numeros.dat');
   {$ifdef Unix}
   Assign(Arch,'の番号.dat');
   {$endif}



   Rewrite(Arch);
   Randomize;
   for i:=1 to 10 do
      Begin
       b:=random(1000);
       Write(Arch,b)
      End;



   Reset(Arch);
   for i:=1 to 10 do
      Begin
       read(Arch,b);
       Writeln(b)
      End;
   close(Arch)
End.
Código fuente 7: Archivo con tipo del tipo de dato integer.
Descargar

El ejemplo anterior crea un archivo que contiene sólo números enteros, generados aleatoriamente. Lo primero que se debe observar del ejemplo es que para grabar o leer, los datos del archivo con tipo, sólo se pueden usar los procedimientos read y write. Readln y Writeln, son procedimientos que se usan sólo con archivos de texto, ya que estos esperan un final de línea para terminar con su operación. Cada vez que se hace una lectura con read este leerá del archivo con tipo la cantidad de bytes que tiene el tipo de dato, que define al archivo, lo mismo sucede con write, que en este caso escribe la cantidad de bytes que tiene el tipo de dato.

El siguiente programa de ejemplo nos muestra el uso del procedimiento seek y la función filesize.


Descargar
{$codepage utf8}

{$ifdef win32}
  Uses sysutils;
{$endif}
{$ifdef Unix}
  Uses sysutils,cwstring; 
{$endif}

Var Arch:File of integer; 
    b:integer;      
    NombreArch:Unicodestring;   
Begin
  NombreArch:='numeros.dat';
  {$ifdef Unix}
  NombreArch:='の番号.dat';
  {$endif}
  NombreArch:=SetDirSeparators(NombreArch);  
  
  if FileExists(NombreArch) then
   Begin
     Assign(Arch,NombreArch);
     reset(Arch);
     seek(Arch,FileSize(Arch)); //se va al ultimo registro
     Write(Arch,9999); //escribe el numero 9999 al final
     seek(Arch,0); //mueve el puntero al inicio del archivo
     While Not(EOF(Arch)) do
        Begin
          Read(Arch,b);          
          Writeln(b)
        End;
     close(Arch)
   End;
End.
Código fuente 8: Uso de seek y filesize.
Descargar

La función filesize devuelve la cantidad de elementos o bloques que contiene un archivo con tipo, y como se puede ver en el ejemplo se usa para indicarle al procedimiento seek, que mueva el puntero del archivo al final del mismo, para luego escribir al final del archivo el numero 9999. Antes de entrar al bucle While que nos muestra el contenido del archivo, se mueve el puntero del archivo al inicio usando seek(Arch,0). Si no se hace esa operación, entonces el bucle while no se ejecutará y por ende no se mostrarán los números almacenados en el archivo. Cada vez que se usa read o write, el puntero de archivo siempre se moverá al siguiente elemento o bloque de bytes del archivo con tipo.

El siguiente programa hace uso de archivos con tipo, usando registros. El programa de ejemplo nos permite almacenar una pequeña libreta de contactos, en donde se usa una técnica para el borrado de los contactos, que consiste simplemente en marcar como borrado el contacto que se quiere borrar, para luego usarlo cuando se ingresa un nuevo contacto.


Descargar
{$codepage utf8}

{$ifdef win32}
  Uses sysutils;
{$endif}
{$ifdef Unix}
  Uses sysutils,cwstring; 
{$endif}


Type TContacto=Record
       Nombre,Apellido:String;
       Correo:String;
       SigLibre:longword;
       Borrado:boolean;
     End;


Var Arch:File of TContacto; 
    NombreArch:Unicodestring;   
    Rpt:byte;
    Contacto:TContacto;


Procedure IngresarContacto;
 Var aux1,aux2:TContacto;     
 Begin
   Write('Nombre:');Readln(contacto.Nombre);
   Write('Apellido:');Readln(contacto.Apellido); 
   Write('Correo:');Readln(contacto.Correo);
   Contacto.Borrado:=false;   
   Contacto.SigLibre:=0;   
   Assign(Arch,NombreArch);
   if Not(FileExists(NombreArch)) 
      then Begin
             Rewrite(Arch);
             aux1.Nombre:='';aux1.Apellido:='';
             aux1.Correo:='';aux1.SigLibre:=0;
             aux1.Borrado:=false;
             Write(Arch,aux1)
             End
      else Reset(Arch);
   seek(Arch,0);
   Read(Arch,aux1);
   if aux1.SigLibre=0
      then Begin //Colocar al final
             seek(Arch,FileSize(Arch));
             Write(Arch,Contacto)
           End	  
      else Begin
             seek(Arch,aux1.SigLibre);
             read(Arch,aux2);
             seek(Arch,aux1.Siglibre);
             Write(Arch,Contacto);
             aux2.Nombre:='';aux2.Apellido:='';
             aux2.Correo:='';aux2.Borrado:=false;
             seek(Arch,0);
             write(Arch,aux2)
           End;
   close(Arch) 
 End;
 
Procedure BorrarContacto;
Var n:longword;
    aux1,aux2:TContacto;
 Begin
  if FileExists(NombreArch) then
   Begin
    Write('Registro a borrar:');Readln(n);
    Assign(Arch,NombreArch);
    Reset(Arch);
   
    if (n>0) and (n<FileSize(Arch)) then
     Begin
      seek(Arch,0);read(Arch,aux1);         
      seek(Arch,n);read(Arch,aux2);   
   
      aux2.SigLibre:=aux1.SigLibre;
      aux2.Borrado:=true;
      aux1.SigLibre:=n;
   
      seek(Arch,0);write(Arch,aux1);         
      seek(Arch,n);write(Arch,aux2)
     End;

    close(Arch);
   End
  else Write('No hay contactos')
 End; 


Procedure MostrarContactos;
Var n:longword;
 Begin
  if FileExists(NombreArch) then
  Begin
   Assign(Arch,NombreArch);
   Reset(Arch);
   seek(Arch,1);n:=1;
   While not(EOF(Arch)) do
     Begin
      read(Arch,contacto);
      if Not (Contacto.Borrado) then
      Writeln('[',n,'] ',Contacto.Apellido,',',
              Contacto.Nombre,',',Contacto.Correo);
      n:=n+1;
     End; 
   Close(Arch);
   Writeln;Writeln;
  End
  Else Writeln('No hay contactos')  
 End; 
 
Begin
  NombreArch:='Contactos.dat';
  NombreArch:=SetDirSeparators(NombreArch);  
  Rpt:=0;
  Repeat
    Writeln('[1] Ingresar Contacto');
    Writeln('[2] Borrar Contacto');
    Writeln('[3] Mostrar Contactos');
    Writeln('[4] Salir');
    Write('Opcion:');Readln(Rpt);
    Case Rpt of
      1: IngresarContacto;
      2: BorrarContacto;
      3: MostrarContactos;
    End;
  Until Rpt=4
End.
Código fuente 9: Pequeña Libreta de Contacto.
Descargar

El primer contacto no se usa y sólo sirve como punto de partida para que el programa ubique los registros o contactos borrados, el programa se asegura que el primer registro al que llamaremos encabezado, siempre tenga en el campo SigLibre el numero del registro que se borro por última vez, y el registro que se borro por última vez también tendrá en su campo SigLibre, el registro anteriormente borrado y así sucesivamente hasta encadenar todos los registros que se hayan borrado. Todos los contactos o registros tienen un campo llamado Borrado de tipo boolean, que cuando el valor es true nos indica que el registro esta marcado como borrado y si es false nos indica que el registro no está borrado.

El programa consta de 3 procedimientos IngresarContacto, BorrarContacto, MostrarContacto.

El procedimiento IngresarContacto, realiza ciertas rutinas de comprobación para saber si el archivo de contactos existe, en caso no exista lo crea y coloca el encabezado; el encabezado nos sirve como punto de partida para saber los registros borrados, la parte más importante de este procedimiento es el siguiente código:

if aux1.SigLibre=0 then
Begin
   //Colocar al final
   seek(Arch,FileSize(Arch));
   Write(Arch,Contacto)
End
else
Begin
   seek(Arch,aux1.SigLibre);
   read(Arch,aux2);
   seek(Arch,aux1.Siglibre);
   Write(Arch,Contacto);
   aux2.Nombre:='';
   aux2.Apellido:='';
   aux2.Correo:='';
   aux2.Borrado:=false;
   seek(Arch,0);
   write(Arch,aux2)
End;

Este código se encarga de verificar si existe un registro o contacto borrado, para ello verifica si el campo SigLibre del primer registro (el encabezado) tiene el valor 0, en caso lo tenga coloca el nuevo contacto al final del archivo, pero en caso no lo tenga hace una serie de operaciones para colocar el nuevo contacto en el contacto marcado como borrado, y al mismo tiempo graba en el encabezado el siguiente registro o contacto libre para ser usado.

El procedimiento BorrarContacto, se encarga de borrar el contacto o registro indicado a través de la variable n, siempre y cuando el registro este dentro del archivo, esto se verifica con la siguiente condición: (n>0) and (n<FileSize(Arch)), una vez se verifica que se puede borrar el registro entonces, se lee el primer registro que es el encabezado y el registro que se quiere borrar, luego se actualiza el registro borrado colocando en su campo SigLibre el numero del anterior registro borrado, este se encontrará en el campo SigLibre del encabezado; después se actualiza el encabezado colocando en su campo SigLibre el nuevo registro borrado, también al registro que se va a borrar se coloca en su campo Borrado el valor true, para indicar que ese registro esta borrado, y finalmente se graban ambos registros en el archivo.

El procedimiento MostrarContacto, se encarga de mostrarnos los registros o campos que tiene el archivo, para ello hace uso de un bucle while que hace el recorrido del archivo hasta llegar al final del archivo, para que este procedimiento no muestre los archivos borrados, este procedimiento hace uso del campo Borrado, para verificar si realmente el registro se ha borrado, un valor true indica que se ha borrado un valor false indica que no se ha borrado el registro.

La función Truncate, es una rutina que trabaja de la mano con seek y permite borrar el contenido del archivo desde la posición en donde se encuentre el puntero del archivo, hasta el final del mismo. Una vez que se trunca el archivo este se cierra. A continuación un Ejemplo:


Descargar
{$codepage utf8}

{$ifdef win32}
  Uses sysutils;
{$endif}
{$ifdef Unix}
  Uses sysutils,cwstring; 
{$endif}

Var Arch:File of integer; 
    b:integer;      
    NombreArch:Unicodestring;   
Begin
  NombreArch:='numeros.dat';
  {$ifdef Unix}
  NombreArch:='の番号.dat';
  {$endif}
  NombreArch:=SetDirSeparators(NombreArch);  

  Assign(Arch,NombreArch);
  
  Writeln('Creando el archivo');
  Rewrite(Arch);
  Randomize;
  for b:=0 to 10 do  Write(Arch,b);
	 
  Writeln('Mostrando');	 
  Reset(Arch);
  While Not(EOF(Arch)) do
    Begin
     read(Arch,b);
     Writeln(b)
    End;   	       
   
  Writeln('Truncado hasta 5');	 
  seek(Arch,5); //mueve el puntero de archivo al 5to entero.
  truncate(Arch); //truncate cierra el archivo, igual que close.
  reset(Arch);
  While Not(EOF(Arch)) do
       Begin
         Read(Arch,b);          
         Writeln(b)
       End;
   close(Arch)
End.
Código fuente 10: Ejemplo de la función Truncate.
Descargar




SIGUIENTE
SIGUIENTE
SIGUIENTE



 
‒ Comentarios y sugerencias.

Agradezco de antemano, todo comentario, sugerencia, y donativo (a través de Paypal me), que ayude a mejorar los contenidos educativos de Conoce 3000. Además, cualquier pregunta o duda que tengas lo puedes hacer por este medio. Pero, todo contenido que pueda resultar ofensivo, malicioso, racista, sexista, discriminatorio, obsceno, vulgar será eliminado.


Comments System WIDGET PACK






PORTADA |  INTERESANTE |  APUNTES |  LIBROS |  GALERIA


Creative Commons License


Todos los textos, imágenes y videos de Conoce3000 estan colocados bajo una licencia : Creative Commons Reconocimiento-NoComercial 3.0 Unported License.