Formato INI: Archivos de Configuración Explicados
El formato de archivo INI es uno de los formatos de configuración más antiguos y reconocidos en la informática. A pesar de no tener un estándar formal y tener docenas de dialectos incompatibles, los archivos INI siguen siendo omnipresentes en sistemas Windows, aplicaciones PHP, motores de juegos, servidores de bases de datos y herramientas de desarrollo. Su atractivo es inmediatamente obvio: texto plano, legible por humanos y lo suficientemente simple como para editarse sin herramientas especializadas. Esta guía cubre la estructura, dialectos, análisis, limitaciones y el panorama moderno de alternativas que han surgido para abordar las deficiencias de INI.
Historia y Orígenes
El formato INI toma su nombre de la extensión .ini utilizada por los archivos de inicialización de Windows. El formato data de finales de los años 80 con las primeras versiones de Windows, que usaban WIN.INI y SYSTEM.INI para almacenar la configuración del sistema. Las aplicaciones DOS habían usado archivos de texto plano similares de clave=valor incluso antes, pero Windows popularizó la estructura en secciones que define al INI hoy.
Microsoft se alejó de los archivos INI en Windows 95, reemplazándolos con el Registro de Windows para la configuración del sistema. Sin embargo, el formato continuó en la configuración a nivel de aplicación — php.ini, my.cnf (MySQL), smb.conf (Samba), archivos de configuración de juegos e innumerables herramientas de desarrollo continúan usando sintaxis estilo INI hoy.
Estructura Básica
Un archivo INI es un archivo de texto plano organizado en secciones, claves y valores:
; Esto es un comentario
# Esto también es un comentario (en muchos dialectos)
[database]
host = localhost
port = 5432
name = production_db
user = app_user
password = s3cr3t
[server]
host = 0.0.0.0
port = 8080
debug = false
workers = 4
[logging]
level = info
file = /var/log/app.log
rotate = daily
max_size = 100MB
La estructura es intuitiva:
- Secciones — delimitadas por
[nombre_seccion]en su propia línea. Los nombres de sección suelen ser insensibles a mayúsculas (aunque los parsers varían). - Claves — el nombre de un elemento de configuración, a la izquierda del separador
=o:. - Valores — el lado derecho del separador. El espacio en blanco alrededor del separador generalmente se ignora.
- Comentarios — las líneas que comienzan con
;o#son comentarios (depende del parser;#no es universalmente reconocido).
Dialectos INI: La Falta de un Estándar
A diferencia de JSON o TOML, INI no tiene una especificación que lo rija. Cada parser implementa sus propias reglas. Esto crea importantes desafíos de portabilidad:
Caracteres de Comentario
| Parser | Comentarios ; |
Comentarios # |
|---|---|---|
Python configparser |
✅ | ✅ (por defecto) |
PHP parse_ini_file |
✅ | ✅ |
Windows GetPrivateProfileString |
✅ | ❌ |
MySQL my.cnf |
✅ | ✅ |
| Git config | ✅ | ✅ |
Separadores Clave-Valor
La mayoría de parsers aceptan clave = valor. Algunos también aceptan clave: valor (Python configparser, Java Properties) o clave valor (sin separador, algunas configuraciones Unix).
Valores Multi-línea
Python configparser soporta valores multi-línea con sangría:
[mensaje]
cuerpo = Esta es la línea uno.
Esta es la línea dos (continuación sangrada).
Esta es la línea tres.
Windows INI (vía GetPrivateProfileString) no soporta valores multi-línea en absoluto.
Python: configparser
El módulo configparser de Python proporciona un robusto parser INI:
import configparser
config = configparser.ConfigParser()
config.read('settings.ini')
# Leer un valor
db_host = config['database']['host']
db_port = config.getint('database', 'port') # Conversión de tipo
debug = config.getboolean('server', 'debug')
# Iterar secciones
for section in config.sections():
print(f"[{section}]")
for key, value in config.items(section):
print(f" {key} = {value}")
# Escribir un archivo INI
config['nueva_seccion'] = {
'clave1': 'valor1',
'clave2': '42',
}
with open('salida.ini', 'w') as f:
config.write(f)
La sección DEFAULT: configparser trata [DEFAULT] especialmente — sus valores sirven como predeterminados para todas las demás secciones:
[DEFAULT]
timeout = 30
retries = 3
[api_v1]
endpoint = https://api.ejemplo.com/v1
; timeout y retries heredados de DEFAULT
[api_v2]
endpoint = https://api.ejemplo.com/v2
timeout = 60 ; sobrescribe DEFAULT
config.getint('api_v1', 'timeout') # Devuelve 30 (de DEFAULT)
config.getint('api_v2', 'timeout') # Devuelve 60 (sobrescrito)
PHP: parse_ini_file
La función parse_ini_file() de PHP está construida para leer archivos estilo php.ini:
<?php
// Analizar en array
$config = parse_ini_file('config.ini', true); // true = procesar secciones
echo $config['database']['host']; // localhost
echo $config['server']['port']; // 8080
// Modo scan para valores tipados
$config = parse_ini_file('config.ini', true, INI_SCANNER_TYPED);
var_dump($config['server']['debug']); // bool(false) — no string "false"
// Escritura INI (no hay función nativa — debe generarse manualmente)
function escribir_ini_file(array $datos, string $ruta): void {
$lineas = [];
foreach ($datos as $seccion => $valores) {
$lineas[] = "[$seccion]";
foreach ($valores as $clave => $valor) {
if (is_bool($valor)) {
$lineas[] = "$clave = " . ($valor ? 'true' : 'false');
} elseif (is_array($valor)) {
foreach ($valor as $item) {
$lineas[] = "{$clave}[] = $item";
}
} else {
$lineas[] = "$clave = $valor";
}
}
$lineas[] = '';
}
file_put_contents($ruta, implode("\n", $lineas));
}
Arrays INI en PHP: PHP extiende el formato INI con soporte de arrays usando sintaxis de corchetes:
[extensions]
allowed_types[] = jpg
allowed_types[] = png
allowed_types[] = gif
allowed_types[] = webp
Esto resulta en que $config['extensions']['allowed_types'] sea un array ['jpg', 'png', 'gif', 'webp'].
Archivos INI del Mundo Real
php.ini
[PHP]
memory_limit = 128M
max_execution_time = 30
upload_max_filesize = 2M
post_max_size = 8M
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED
[Date]
date.timezone = Europe/Madrid
[MySQLi]
mysqli.default_port = 3306
MySQL my.cnf
[mysqld]
user = mysql
datadir = /var/lib/mysql
port = 3306
bind-address = 127.0.0.1
max_connections = 151
innodb_buffer_pool_size = 128M
slow_query_log = 1
long_query_time = 2
[client]
port = 3306
default-character-set = utf8mb4
Git Config
[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = https://github.com/usuario/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[user]
name = Pablo Cirre
email = pablo@ejemplo.com
INI vs Alternativas Modernas
| Característica | INI | JSON | TOML | YAML |
|---|---|---|---|---|
| Legibilidad humana | ✅ Excelente | ✅ Buena | ✅ Excelente | ✅ Excelente |
| Estándar formal | ❌ No | ✅ RFC 8259 | ✅ TOML v1.0 | ✅ YAML 1.2 |
| Valores tipados | ❌ Solo strings | ✅ Tipos nativos | ✅ Tipos nativos | ✅ Tipos nativos |
| Arrays | ⚠️ Extensión | ✅ Nativo | ✅ Nativo | ✅ Nativo |
| Estructuras anidadas | ❌ No | ✅ Ilimitadas | ✅ Tablas anidadas | ✅ Ilimitadas |
| Comentarios | ✅ Sí | ❌ No | ✅ Sí | ✅ Sí |
Cuándo Usar INI
Elige INI cuando:
- Se espera edición por usuarios no técnicos — INI es el formato más accesible
- La configuración es simple y plana (sin estructuras anidadas)
- El entorno ya usa INI (aplicaciones PHP, MySQL, Samba, software legacy de Windows)
- Se requiere compatibilidad con herramientas existentes
Elige TOML en su lugar cuando:
- Necesitas valores tipados (enteros, booleanos, fechas, arrays) sin ambigüedad
- Se necesita anidamiento moderado (uno o dos niveles)
- Estás comenzando un nuevo proyecto y la compatibilidad con INI no es una restricción
Elige JSON cuando:
- La configuración será consumida por muchos lenguajes y entornos
- Se requiere un estándar formal e inequívoco
- Los comentarios no son necesarios
Conclusión
La notable permanencia del formato INI proviene de su radical simplicidad: cualquiera que pueda abrir un editor de texto puede leer y editar un archivo INI. Su falta de un estándar formal es simultáneamente su mayor debilidad (parsers incompatibles, fragmentación de dialectos) y su mayor fortaleza (cada entorno ha implementado su propia versión, garantizando ubicuidad). Comprender la estructura de INI, las diferencias de comportamiento entre los principales parsers y sus limitaciones en comparación con TOML y JSON te permite tomar decisiones de formato informadas para nuevos proyectos y trabajar de forma segura con el enorme ecosistema heredado de software configurado con INI que continúa ejecutando la infraestructura del mundo.
Conversiones relacionadas
Conversiones frecuentes del catálogo: