En Perl un filehandle es el nombre una conexión de entrada/salida que conecta nuestro proceso Perl
con el mundo exterior. Esto es, se trata del nombre de una conexión, no necesariamente
del nombre de un fichero. Existen seis filehandles
que son especiales:
STDIN,
STDOUT,
STDERR,
DATA,
ARGV y
ARGVOUT.
Para abrir una conexión se utiliza el operador open
. Por ejemplo:
if (open FILE, "alus.txt" ) { ... # Para lectura } if (open FILE, "<alus.txt" ) { ... # Para lectura } if (open FILE, ">alus.txt" ) { ... # Para escritura } if (open FILE, ">>alus.txt" ) { ... # Para añadir }
El operador open
devuelve verdadero o falso, dependiendo de
si la operación pudo realizarse con éxito o no.
Se puede usar una expresión escalar en lugar del especificador de fichero. Por ejemplo:
my $outfile = "alu.txt"; open FILE, "> $outfile";
Observe el espacio después del ``mayor que''. Asi se evitan extrañas conductas, si por ejemplo
$outfile
es algo asi como >alu.txt
, se podriá producir un append
(esto es >>
) en vez de una escritura (>
).
Para cerrar el fichero use el operador close
:
close FILE;
Perl cierra automáticamente un fichero cuando se reabre o bien cuando termina la ejecución del programa.
La típica frase Perl para abrir un fichero es:
open FILE, ">>logfile" or die "No se puede crear el fichero: $!";Esta expresión aprovecha la evaluación en circuito corto. La función
die
imprime el mensaje a STDERR
y hace que nuestro
programa termine con un estatus distinto de cero.
Además añade al mensaje el nombre del programa y el número de línea en caso de
que el mensaje de error no termine en un retorno de carro (\n
).
La variable especial $!
contiene el último mensaje de error del sistema
operativo.
STDIN
usando el operador
de lectura <FILEHANDLE>
. Veamos un ejemplo:
my $user = shift; open PASSWD, "/etc/passwd" or die "Se esperaba un sistema Unix. $!"; while (<PASSWD>) { chomp; if (/^$user:/) { print "$_\n"; } }
La variable especial $/
contiene el separador de lectura, que por defecto
es un \n
. Asi, si le asignamos $/ = '.';
en la siguiente lectura
se leerá hasta el próximo punto o hasta el final del fichero si no lo hubiera.
Asignarle a $/
la cadena vacía ""
hace que se lea hasta el siguiente
párrafo (esto es, hasta la siguiente aparición de dos o más líneas en blanco).
Cuando tiene el valor undef
se leerá todo el resto del fichero.
undef $/; $x = <FILE>; # Ahora $x contiene todo el fichero
Considere el siguiente código:
open FILEHANDLE, shift; while (<FILEHANDLE>) { print; }¿Existe el riesgo de ``muerte'' prematura debido a que una línea contenga sólamente
"0"
?
Pruebe con varios posibles ficheros de entrada. Observe que el operador
de lectura <FILEHANDLE>
incluye el retorno de carro \n
en \$_
.
El operador select
modifica la salida por defecto.
En vez de STDOUT
el fichero especificado será utilizado por
defecto. La variable especial $|
, cuando vale 1, hace que los buffers
de salida se vacíen inmediatamente a la salida por defecto.
> cat select.pl #!/usr/bin/perl -w my $user = shift; open LOG, ">/tmp/log.file" or die "Se esperaba un sistema Unix"; select LOG; $| = 1; print "Esto es una prueba\n"; select STDOUT; print "Esto es otra prueba\n"
Veamos una ejecución:
nereida:~/perl/src> select.pl Esto es otra prueba nereida:~/perl/src> cat /tmp/log.file Esto es una prueba
La variable $,
contiene el separador para el operador print
.
Normalmente no hay separación entre los argumentos de print
.
Esto puede modificarse como muestra el ejemplo:
print 1,2,3 # Salida: 123 $, = ','; print 1,2,3 # Salida: 1,2,3 $, = ';'; print 1,2,3 # Salida: 1;2;3
Perl normalmente no separa dos salidas realizadas en dos llamadas
consecutivas a la sentencia print
. Para ello se puede
usar la variable $\
. Vea el ejemplo:
$\ = "\n***\n"; print "uno"; print "dos";La salida será:
uno *** dos ***
Si reabrimos un fichero, el viejo será cerrado automáticamente. Si se trata de uno de los tres ficheros estándar y falla la reapertura se restaura el original. Así para redirigir los errores escribiríamos:
open STDERR, ">>/home/casiano/.error.log" or die "No se pudo abrir fichero de errores: $!";
Perl utiliza -e $filevar
para comprobar la existencia de un fichero cuyo nombre es el guardado en la variable
$filevar
. Si el fichero existe el resultados es verdadero; en otro caso es falso. Por ejemplo:
$name = "index.html"; if (-e $name) { print "Ya existe un fichero denominado $name\n"; } else { print "No existe un fichero denominado $name\n"; }
He aqui otro ejemplo:
if (-e "index.html" && -e "index.cgi") { print "Encontrados.\n"; }
Existen otros operadores.
Por ejemplo, -r $filevar
es cierto si el fichero cuyo nombre se guarda en $filevar
existe y es de lectura.
Análogamente, -w $filevar
comprueba si es de escritura.
print "Donde? "; $filename = <STDIN>; chomp $filename; if (-r $filename && -w $filename) { # El fichero existe y es de lectura y escritura ... }
La tabla 2.1 contiene algunos de los operadores mas importantes.
Estos operadores pueden usarse indistintamente sobre filehandles
o nombres de fichero.
Por ejemplo:
if (-x SOMEFILE) { # SOMEFILE es ejecutable }
Si no se especifica el nombre del fichero,
el operador por defecto es la variable $_
.
Por ejemplo:
foreach (@some_list_of_filenames) { print "$_ es de lectura\n" if -r; # Lo mismo que -r $_ }
Si se quiere obtener información más detallada como el número de enlaces a un
fichero o el uid
del propietario de un fichero es necesario recurrir a
la función stat. El operando de stat
es un fichero o un
nombre de fichero. La función stat devuelve
bien una lista vacía (en caso de error) o una lista de 13 elementos
(véase la tabla 2.2).
|
Los argumentos atime
, mtime
y ctime
indican cuantos segundos han pasado desde el comienzo de 1970 MUT
(Midnight Universal Time).
En el siguiente ejemplo, en la línea 1 el uso del operador glob
nos permite
la expansión de los comodines tipo shell:
DB<1> @f = glob('xml*') DB<2> p "@f" xml xmlparser.pl xmlparserinput.xml DB<3> @a = stat "xmlparser.pl" DB<4> x @a 0 2051 1 2171300 2 33261 3 1 4 1007 5 1007 6 0 7 191 8 1112287076 9 1087853581 10 1099385099 11 4096 12 8
La función localtime
permite convertir números en formato MUT en una cadena tipo fecha:
DB<1> @a = stat "xmlparser.pl" DB<2> use constant mtime => 9 DB<3> x $a[mtime] 0 1087853581 DB<4> p scalar(localtime $a[mtime]) Mon Jun 21 22:33:01 2004
Cuando se llama a stat
sobre un enlace simbólico, stat
devuelve información sobre el fichero apuntado, no sobre el enlace.
Si se trata de un enlace en vez de un fichero, use la función lstat
.
Si el operando no es un enlace simbólico lstat
devuelve la
misma información que stat
. Cuando no se indica operando,
ambos stat
y lstat
usan la variable por defecto $_
.
La función openhandle en Scalar::Util
permite saber si una expresión es un manejador de
fichero (o un atado mediante tie
de un manejador).
openhandle FHRetorna
FH
si FH
puede ser usado como manejador y esta abierto.
En otro caso retorna undef
:
$fh = openhandle(*STDIN); # \*STDIN $fh = openhandle(\*STDIN); # \*STDIN $fh = openhandle(*NOTOPEN); # undef $fh = openhandle("scalar"); # undef