este espacio está libre ¿deseas utilizarlo? haz clic aquí.

   Secciones

   Inicio
   Documentos
   Programas
   Links
   Proyectos
   Libros

   Actualizaciones & Foro

   Avisar al actualizar
   Foro Delphiladero

   Otras

   Contacto
   Agregar a favoritos
   Vota por nosotros

 

 

 

inicio » documentos » intro al registro y los ini - parte 2


indice

Archivos INI
      Qué son

      Su estructura
      Cómo leerlos y modificarlos
      Ultimos comentarios antes de los ejercicios


« archivos ini »


qué son

Hace un tiempo los programas Windows usaban archivos de configuración (*.INI) para almacenar información relacionada con las aplicaciones. Sin embargo, con la aparición de los Windows de 32 bits (Win 95 en adelante), se decidió que la nueva forma de hacer las cosas era usando el Registro. Allí se debía guardar toda la información relacionada con la configuración de las aplicaciones y del sistema operativo. Es así que el "saber popular" de hoy en día nos dice que el uso de los INI está fuera de moda y que lo que hay que hacer es usar el Registro.

A pesar de ello, los archivos INI tienen muchas ventajas que el Registro no tiene. En primer lugar, al borrar un programa, también estaremos borrando todos los archivos INI que guardaban las configuraciones de ese programa, a diferencia de lo que generalmente ocurre cuando estas configuraciones se guardan en el Registro. No es raro oir que programas que habíamos borrado hace un tiempo siguen teniendo claves aquí y allá, y algunas más que nunca descubriremos donde están. En segundo lugar, los archivos INI, al ser archivos de texto son mucho más fáciles de modificar. Y por último, la frase "divide y triunfarás" ¿la conoces?. El Registro se ha convertido en una base demasiado grande y cuanto más grande más problemas.

Como notarás, yo sigo utilizando los archivos INI para almacenar todas las configuraciones de mis programas. Sin embargo, mientras esté programando bajo Windows nunca podré librarme de utilizar el Registro, ya que en él se guardan todas las configuraciones del sistema y de muchos de los programas que se encuentran instalados en él.

Muy bien, pero todavía no me has dicho qué son los archivos INI. Bueno, los archivos INI son simples archivos de texto que se han popularizado por almacenar configuraciones de los programas y del sistema. El archivo INI más popular es el WIN.INI, que Windows todavía hoy utiliza para almacenar configuraciones del sistema operativo.


su estructura

El siguiente es un extracto del archivo WIN. INI:

[Desktop]
Wallpaper=C:\WINDOWS\PLUS!.BMP
TileWallpaper=0
WallpaperStyle=0
Pattern=(None)

Para poder acceder a un valor de un archivo INI se necesitan 2 cosas: el nombre de la sección y el nombre de la clave. Los nombres de las secciones se escriben entre corchetes ('[Desktop]' es una sección) y separan al archivo INI en porciones lógicas. El nombre de la clave puede ser cualquier expresión que no incluya caracteres especiales (!@#$%^=, etc.) ni espacios en blanco. Esta regla, sin embargo, no se aplica para el nombre de una sección. Por otra parte, es importante notar que el valor de una clave y el nombre de la clave están separados por el signo '=' y que por lo tanto todo lo que se encuentre a su derecha será considerado el valor de esa clave.

Nota: ¡Ciudado! La "restricción" de caracteres para el nombre de una clave es más bien una recomendación y no una restricción real. Sin embargo, es MUY recomendable tenerla en cuenta a la hora de elegir un nombre.

Entonces, para obtener la ruta del archivo del papel tapiz, tendríamos que buscar en la clave "Wallpaper" de la sección "Desktop" del archivo "WIN.INI".


como leerlos y modificarlos

Para no tener que manejar estos archivos "a la interperie", Delphi, al igual que con el Registro, nos provee una clase para poder modificar los archivos INI de una forma muy sencilla. Antes de ver cómo funciona TIniFile, veamos cuales son sus propiedades y métodos más importantes.

Propiedad

Descripción

FileName

Almacena el nombre del archivo INI en el cuál se podrán realizar las operaciones de lectura/escritura.

Método

Descripción

DeleteKey

Borra los datos asignados a la clave especificada.

EraseSection

Borra toda la sección especificada, incluyendo todas las claves y valores que se encontraban en ella. 

ReadSection

Devuelve los nombres de todas las claves de la sección especificada.

ReadSections

Devuelve los nombres de todas las secciones existentes.

ReadSectionValues

Devuelve los valores pertenecientes a todas las claves de la sección especificada.

ReadString, ReadBool, ReadDate, ReadTime, ReadDateTime, ReadFloat, ReadInteger.

Todos estos métodos realizan la misma operación: leer datos desde el archivo INI. La única diferencia es que cada uno lee diferentes tipos de datos.

WriteString, WriteBool, WriteDate, WriteTime, WriteDateTime, WriteFloat, WriteInteger.

Todos estos métodos realizan la misma operación: escribe datos desde el archivo INI. La única diferencia es que cada uno escribe diferentes tipos de datos.

Bueno, ahora si, llegó la hora de ver a TIniFile en acción. Veamos cómo hacer el mismo programa que guardaba configuraciones (tamaño, posición, etc.) en el Registro, pero esta vez guardándolas en un archivo INI.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  IniFiles, StdCtrls, ToolWin, ComCtrls, Menus;

type
  TForm1 = class(TForm)
    btnAbrir: TButton;
    ToolBar1: TToolBar;
    MainMenu1: TMainMenu;
    mnuOpcionesToolbar1: TMenuItem;
    RichEdit1: TRichEdit;
    OpenDialog: TOpenDialog;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnAbrirClick(Sender: TObject);
  private
    UltimoAbierto: string;
    procedure AbrirArchivo(Ruta: string);
  public
    { Public declarations }
end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const RutaINI: string = 'c:\windows\pruebaini.ini';

procedure TForm1.AbrirArchivo(Ruta: string);
begin
  { abrimos el archivo y realizamos algunas modificaciones a la barra de título }
  try
    if Ruta <> '' then begin
      RichEdit1.Lines.LoadFromFile(Ruta);
      Caption := 'Notas - ' + Ruta;
      UltimoAbierto := Ruta;
    end;
  except
    on EFOpenError do
      ShowMessage('El archivo que se abrió la última vez ya no existe!');
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var Ini: TIniFile;
    SeccionExiste: boolean;
begin
  Ini := TIniFile.Create(RutaINI);
  try
    SeccionExiste := Ini.SectionExists('Tamaño');

    { obtenemos todos los datos necesarios del Registro }
    if SeccionExiste then begin
      if Ini.ReadBool('Tamaño', 'Maximizado', False) = False then begin
        Left := Ini.ReadInteger('Tamaño', 'Left', (Screen.Width div 2) - 
	     (Width div 2));
        Top := Ini.ReadInteger('Tamaño', 'Top', (Screen.Height div 2) - 
	     (Height div 2));
        Height := Ini.ReadInteger('Tamaño', 'Height', 480);
        Width := Ini.ReadInteger('Tamaño', 'Width', 696);
      end else
        WindowState := wsMaximized;

      ToolBar1.Visible := Ini.ReadBool('Otras', 'ToolBar1', True);
      mnuOpcionesToolBar1.Checked := ToolBar1.Visible;

      AbrirArchivo(Ini.ReadString('Otras', 'UltimoAbierto', ''));
    end;
  finally
    Ini.Free;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var Ini: TIniFile;
begin
  Ini := TIniFile.Create(RutaINI);
  try
    { guardamos todos los datos en el archivo INI }
    Ini.WriteBool('Tamaño', 'Maximizado', WindowState = wsMaximized);
    Ini.WriteInteger('Tamaño', 'Left', Left);
    Ini.WriteInteger('Tamaño', 'Top', Top);
    Ini.WriteInteger('Tamaño', 'Height', Height);
    Ini.WriteInteger('Tamaño', 'Width', Width);

    Ini.WriteBool('Otras', 'ToolBar1', mnuOpcionesToolBar1.Checked);
    Ini.WriteString('Otras', 'UltimoAbierto', UltimoAbierto);
  finally
    Ini.Free;
  end;
end;

procedure TForm1.btnAbrirClick(Sender: TObject);
begin
  if OpenDialog.Execute then
    AbrirArchivo(OpenDialog.FileName);
end;

end.

Como verás la traducción de una forma a la otra es muy sencilla y todo lo que tuvimos que hacer es cambiar un par de líneas. Son 2 formas de hacer exactamente lo mismo. Ambos métodos tienen sus ventajas y desventajas que debes tener en cuenta a la hora de elegir. Si me pides mi opinión, definitivamente prefiero utilizar los archivos INI. Sin embargo, mis gustos no tienen por qué ser los tuyos. Te recomendaría que probaras con ambos y decidas cuál te resulta más cómodo.

En cuanto al ejemplo anterior hay algunos puntos que sería interesante aclarar. Seguramente al leer el código te habrás hecho alguna de estas preguntas:

a) ¿Qué pasa si llamamos al constructor de TIniFile con un nombre de archivo inexistente como parámetro?
Rta: Si lo que hacemos luego de crear el objeto es intentar leer el archivo, no pasa nada; en cambio si lo que hacemos es intentar escribir el archivo se crea automáticamente.

b) ¿Qué pasa si intentamos escribir un valor en una sección inexistente, y por lo tanto en una clave inexistente?
Rta: Automáticamente se crean la sección y la clave. En el caso de que la sección ya exista pero la clave no, se crea sólo la clave, por supuesto.

c) ¿Qué pasa si la sección/clave que intentamos leer no existe o no hay valores asignados a esa clave?
Rta: Simplemente ReadLoQueSea devuelve el parámetro Default.

Eso es todo lo relacionado con los archivos INI. Sin embargo, no quisiera terminar este artículo sin antes mencionar que, aunque no las hemos utilizado en el ejemplo anterior, la clase TIniFile viene también con 2 métodos para leer secciones enteras de una vez. Esto resulta útil cuando se desconocen los nombres de las claves de una sección en particular. Estos métodos están definidos de la siguiente manera:

procedure ReadSection (const Section: string; Strings: TStrings);
procedure ReadSectionValues(const Section: string; Strings: TStrings);

Pero como digo siempre, pocas palabras y más ejemplos. Veamos a estos métodos en acción para comprender cuál es su uso más común. 

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, IniFiles;

type
  TForm1 = class(TForm)
    lbSection: TListBox;
    lbSectionValues: TListBox;
    lbSections: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure lbSectionsClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  WinIni : TIniFile;
begin
  WinIni := TIniFile.Create('WIN.INI');
  try
    WinIni.ReadSections(lbSections.Items);
  finally
    WinIni.Free;
  end;
end;

procedure TForm1.lbSectionsClick(Sender: TObject);
var
  WinIni : TIniFile;
begin
  lbSection.Clear;
  lbSectionValues.Clear;
  WinIni := TIniFile.Create('WIN.INI');
  try
    WinIni.ReadSection(lbSections.Items.
	Strings[lbSections.ItemIndex], lbSection.Items);
    WinIni.ReadSectionValues(lbSections.Items.
	Strings[lbSections.ItemIndex], lbSectionValues.Items);
  finally
    WinIni.Free;
  end;
end;

Nota: Si eres un buen observador habrás notado que al crear el objeto WinIni el parámetro es 'WIN.INI' y no 'C:\Windows\WIN.INI'. Esto se debe a que en general los archivos INI se encuentran en el directorio Windows y por lo tanto con sólo especificar el nombre del archivo basta. Si deseas trabajar con un archivo localizado en otro directorio debes especificar la ruta completa.

La diferencia entre ReadSection y ReadSectionValues es que ReadSection devuelve sólo el nombre de todas las claves ("Wallpaper") pertenecientes a la sección especificada, mientras que ReadSectionValues devuelve no sólo los nombres sino también los valores de esas claves. Por ejemplo, mientras ReadSection devuelve los siguientes valores al buscar en la sección Desktop del WIN.INI:

Wallpaper
TileWallpaper
WallpaperStyle
Pattern

ReadSectionValues devuelve:

Wallpaper=C:\WINDOWS\PLUS!.BMP
TileWallpaper=0
WallpaperStyle=0
Pattern=(None)

Bueno, ahora sí hemos concluido. Pero arriba esos ánimos, con cada final hay un nuevo comienzo. Revisa y no te quedes con ninguna duda. Los espero la próxima, tratando vaya uno a saber qué tema "complicado". ¡Suerte!


últimos comentarios

He intentado resumir en este artículo todo lo que debes saber para poder manipular el Registro y los archivos INI. Espero hayas disfrutado esta lectura y lo que es más importante espero haber motivado tu espíritu de aprendizaje y borrado la creencia popular de que programar es MUY complicado. Ahora todo depende de ti. Lee mucho, hazte muchas preguntas sobre lo que lees, trata de encontrarles una respuesta y nunca pero nunca te quedes con una sola visión de cómo hacer las cosas.

Cualquier duda, crítica o sugerencia que tengas por supuesto puedes escribirme y lo más pronto que pueda trataré de responderte.


Recomienda este documento a un amigo.
Recuerda enviarme tus comentarios sobre el artículo.


«anterior - Indice - siguiente»


 Copyright © Pablo Castagnino 2000-2002. Todos los derechos reservados.


Puedes ayudarnos

¿Conoces algún documento enteramente en español que pueda resultar interesante para nuestra comunidad delphiadicta?

Coméntanos de él aquí.


Vota por nosotros