Manipular Archivos

Para que Perl pueda manipular un archivo utiliza lo que es denominado "filehandle" o "file descriptor", este "filehandle" es una referencia hacia el archivo en cuestión, inclusive en todo sistema Unix siempre existen 3 , estos son STDIN,STDOUT,STDERR, que indican "Standard Input","Standard Output" y "Standard Error" respectivamente, estrictamente hablando no son "archivos", pero se sigue escribiendo y leyendo de ellos, estos tres "filehandles" representan nuestro "monitor".

Abrir un Archivo para Lectura

Para abrir un archivo se utiliza el parámetro OPEN , seguido el nombre del "filehandle" y finalmente el archivo.

open (TRIO, "usuarios");

La linea anterior intenta abrir el archivo usuarios bajo el "filehandle" llamado TRIO , por lo que para manipular este archivo (usuarios) se utilizará el "filehandle" TRIO.Si desea leer todas las lineas de un archivo y enviarlas a pantalla (STDOUT) se utilizaría la siguiente secuencia de comandos:

#!/usr/local/perl
OPEN (DATOS,"/home/misdatos.txt");
WHILE (<DATOS>) {
  chomp; 
  print "Renglon: $_ "
}

La primer linea indica que es un programa en Perl, posteriormente se abre el archivo misdatos.txt ubicado en el directorio home con el "filehandle" DATOS ; posteriormente se entra en un ciclo WHILE que toma como argumento el "filehandle" DATOS , esto implica leer renglon por renglon el archivo en cuestión hasta que se termine su lectura. Mientras se esta ejecutando el ciclo se debe eliminar el salto de renglón ( Vea función chomp ) de cada linea y esta debe ser enviada a pantalla ( print ), en este caso merece atención especial el parámetro $_ , el cual indica el valor del renglón del ciclo , esto es , conforme avanza el ciclo la variable $_ toma el valor de cada renglón.

Aunque este ejemplo es limitado, el verdadero poder de Perl recae en el uso de variables, si se utiliza STDIN para leer el archivo que debe ser abierto, se vacían los datos en un arreglo o hash y se substituyen o traducen valores es posible imitar aunque limitadamente el funcionamiento de una base de datos ; para poder realizar un programa de este tipo aun es necesario saber como escribir a un archivo utilizando Perl.

Abrir un Archivo para Escritura

El abrir un archivo ("flat file") para actualizar o escribir información puede presentar varios problemas , pero en ocasiones es posible y necesario realizar este tipo de acciones que seran descritas a continuación.

#!/usr/bin/perl 
print "Que linea desea agregar al Archivo "cableado" ?  " ;
$linea = <STDIN>
chomp($linea);
open(LECTURA,">> cableado") || die "No pudo abrirse: $!";
print LECTURA "$linea";
close(LECTURA);

El ejemplo anterior solicita una linea el ejecutarse el programa (vía <STDIN>), y posteriormente se intenta abrir el archivo nombres para insertar el valor de la linea.. Si observa los parámetros que toma el comando open notara que el nombre del archivo cableado inicia con >> , esto indica que se podrá escribir al final del archivo "cableado", esto es, agregar lineas a aquellas ya existentes en el archivo.

Además de lo anterior también notará los parámetros ( || die "No pudo abrirse: $!"; ), el parámetro || es la condicional OR en Perl, lo cual garantiza que en dado caso no ser posible abrir el archivo cableado se envíe el mensaje No pudo abrirse : $!" , la variable $! indica el error generado; el símbolo ! no es signo de exclamación, es parte de la simbología de la variable del error.

Continuando con la secuencia del programa, se escribe al archivo cableado mediante el uso del "filehandle" (LECTURA) que le fue asignado , en esta linea notará que el comando print toma como argumento el "filehandle" LECTURA , esto es necesario ya que como se mencionó al inicio: todo comando utiliza los "file handles" que siempre existen , por lo tanto si deseamos enviar la información a otro lugar que no sean los "file handles" comunes (el monitor) es necesario este tipo de especificación. Finalmente se utiliza el comando CLOSE que toma como argumento el "filehandle", esto generalmente no es necesario ya que perl automáticamente cerrara el archivo ("filehandle") una vez que termine el programa.

Otra variación para escribir

En muchas ocasiones no se desea agregar lineas al final del archivo sino a su inicio, para esto existe la siguiente variación.

#!/usr/bin/perl 
print "Que linea desea agregar al Archivo "cableado" ?  " ;
$linea = <STDIN>
chomp($linea);
open(LECTURA,"> cableado") || die "No pudo crearse: $!";
print LECTURA "$linea";
close(LECTURA);

En el programa anterior se utilizo solo una > , esto indica que la escritura se realizará al inicio del archivo , sin embargo, el uso de > eliminará el resto del contenido del archivo , por lo tanto tome extrema precaución al utilizarlo ya que eliminara TODA la información del archivo.

En caso de ser necesario escribir al inicio de un archivo que contenga 1000 o 2000 lineas sin el peligro de eliminar el contenido existente puede utilizar el parámetro +<

#!/usr/bin/perl 
print "Que linea desea agregar al Archivo "cableado" ?  " ;
$linea = <STDIN>
chomp($linea);
open(LECTURA,"+< cableado") || die "No pudo crearse: $!";
print LECTURA "$linea";
close(LECTURA);

Lo anterior agregaría las lineas a la parte inicial del archivo pero aunque se conservarían las 1000 o 2000 lineas restantes, el contenido de las lineas iniciales seria sobre-escrito. Para evitar esto seria necesario escribir una función para dejar espacio al inicio del archivo.

Aunque se han mencionado serias limitaciones sobre la manipulación de archivos, estas herramientas son imprescindibles para un administrador de sistemas de Linux que manipula "flat files" casi diariamente. Pero aun falta otra consideración sobre el uso de "flat files" cuando son utilizados por aplicaciones de servidor .

Restringiendo el Acceso a "Flat Files" con "LOCKS"

Cuando un administrador de sistemas modifica un "flat file" por lo general este solo manipulará su contenido a determinado tiempo, sin embargo, cuando se utiliza un "flat file" para guardar información de una aplicación de servidor es muy posible que este "flat file" sea manipulado al mismo tiempo por dos o más procesos ("personas"), esto es uno de los problemas al actualizar o escribir información a un "flat file" , para evitar este conflicto es posible utilizar lo que es denominado "LOCK" o candado, este "LOCK" permite que solo un proceso ("persona") sea capaz de escribir al archivo en cuestión a determinado tiempo. Este "LOCK" no es ninguna propiedad especial de Perl, ya que todo sistema operativo posee un mecanismo de este tipo, desde los diferentes sabores de *nix hasta Windows, sin embargo, para facilitar el uso de "LOCKS" en Perl, se utiliza la función flock la cual adquiere un "LOCK" sobre un archivo.

Exceso de LOCKS..mejor una Base de Datos

Si empieza a utilizar LOCKS en un programa en más de una ocasión es conveniente re-analizar de nuevo sus requerimientos, ya que es posible que su información estuviera más segura en una base de datos que mantuviera su información y administrara estos "LOCKS" por usted, en efecto cumpliendo la prueba del ACIDo

El uso de una base de datos no solo garantizará la integridad de información sino facilitará su acceso también, en vez de utilizar secuencias como

:
WHILE (<DATOS>) {
   if { 
    ... 
} else { 
 .....  
}

para extraer e insertar información, será posible utilizar el lenguaje declarativo SQL ("Structured Query Language") que utilizan las bases de datos:

 select * from usuarios where nombre = 'gabriel';
 insert into telefonos values('534525','monterrey');

Considerando que ya existen varias implementaciones Open-Source para Bases de Datos (Postgres,MySQL), es muy conveniente indagar sobre esta posibilidad de guardar información .

Links: