domingo, 11 de marzo de 2018

Guardar y leer registros en archivos binarios.

Hay dos maneras de hacer esto, con AssingFile o con TFileStream. Prefiero AssingFile, pues se pueden hacer cosas que no se pueden con stream, por ejemplo mover el puntero hacia un registro (aunque solo en modo lectura) mediante el procedimiento Seek y también podemos usar la función FilePos para averiguar sobre qué registro está el puntero. Agregar datos a un archivo binario no se puede ni con AssigFile ni con FileStream, siempre debemos cargar los datos en memoria y re-escribir todo el archivo, lo cual hoy no es la gran cosa debido a la cantidad de sobra de memoria RAM que tiene cualquier ordenar y la velocidad de procesamiento.

En este ejemplo guardaremos registros con nombres de empresas, número ID y nombre de la base de datos, algo simple. Como buffer usaremos un array (vector o matriz unidimensional) de registros.

Código:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics,
    Dialogs, StdCtrls;

type

  { TForm1 }

    TForm1 = class(TForm)
    BGuardar: TButton;
    BLeer: TButton;
    BAgregar: TButton;
    edID: TEdit;
    EdEmpresa: TEdit;
    EdBD: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Memo1: TMemo;
    procedure BAgregarClick(Sender: TObject);
        procedure BGuardarClick(Sender: TObject);
      procedure BLeerClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
    private
        { private declarations }
    public
        { public declarations }
    end;
type
    TReg=record
      ID:Integer;
      Empresa:string[100];
      BD:string[100];
  end;

var
    Form1: TForm1;
    archivo:String;
    aReg:array[0..99] of TReg;
    cantReg:Integer;


implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  archivo:=GetCurrentDir+PathDelim+'datareg.bin';
  cantReg:=0;
  if FileExists(archivo) then BLeerClick(Sender);
  //Si el archivo existe lo carga al array
end;

procedure TForm1.BGuardarClick(Sender: TObject);
var
  FReg:File of TReg; //Archivo que contendrá registros tipo TReg
  i:Integer;
begin
  AssignFile(FReg,archivo);  //Vinculamos el archivo
  Rewrite(FReg);             //Lo vamos a sobreescribir
  for i:=0 to cantReg-1 do //Recorremos el array y lo escribimos
                           //con Write
  begin
    Write(FReg,aReg[i]);
 end;
  CloseFile(FReg);   //Cerramos el archivo
end;

procedure TForm1.BLeerClick(Sender: TObject);
var
  FReg:File of TReg; //Archivo que contendrá registros tipo TReg
  i:Integer;
begin
  AssignFile(FReg,archivo); //Vinculamos el archivo
  Reset(FReg); //Lo abrimos en modo solo lectura
  i:=0;
  while not (EOF(FReg)) do      //Lo cargamos al array
  begin
    Read(FReg,aReg[i]);
    Memo1.Lines.Add(IntToStr(aReg[i].ID)+' '+aReg[i].Empresa+' '+
    aReg[i].BD);
    Inc(i);
    Inc(cantReg);
  end;
  CloseFile(FReg);  //Cerramos el archivo
end;

procedure TForm1.BAgregarClick(Sender: TObject);
begin
  aReg[cantReg].ID:=StrToInt(edID.Text);//Agregamos solo al array, 
                                        //no al archivo.
  aReg[cantReg].Empresa:=EdEmpresa.Text;
  aReg[cantReg].BD:=EdBD.Text;
  Inc(cantReg);
  Memo1.Lines.Add('aReg['+IntToStr(cantReg-1)+']: '+EdEmpresa.Text);
end;

end.


En el registro debemos definir la longitud de los strings.
El primer registro de un archivo binario está en la posición 0 (cero).
No hay forma de agregar un registro a un archivo binario, como sí podemos hacerlo con archivos de texto plano, siempre ha que sobreescribir todo el archivo, de ahí ReWrite.
Al utilizar AssignFile podemos acceder mediante Seek a un determinado registro conociendo su posición y leerlo.

Código fuente:  archivosbinarios.7z (incluye e archivo binario con 5 registros).

o en GitLab



No hay comentarios:

Publicar un comentario