¿Cómo puedo comprobar si un filehandle está abierto en Perl? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Hay alguna forma de comprobar si un archivo ya está abierto en Perl? Quiero tener acceso a un archivo de lectura, así que no requiere flock.

 open(FH, "<$fileName") or die "$!\n" if (<FILE_IS_NOT_ALREADY_OPEN>);
 #  or something like
 close(FH) if (<FILE_IS_OPEN>);
Author: brian d foy, 2009-02-06

6 answers

Por favor vea la respuesta respecto a openhandle() de Scalar::Util. La respuesta que originalmente escribí aquí fue una vez lo mejor que podíamos hacer, pero ahora está muy anticuada.

 38
Author: chaos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:31

El módulo Escalar::Util proporciona el openhandle() función para esto. A diferencia de fileno(), maneja los manejadores de archivos perl que no están asociados con los manejadores de archivos del sistema operativo. A diferencia de tell () , no produce advertencias cuando se usa en un manejador de archivos sin abrir Desde la documentación del módulo :

Openhandle FH

Returns FH if FH may be used as a filehandle and is open, or FH is a tied handle. Otherwise "undef" is returned.

   $fh = openhandle(*STDIN);           # \*STDIN
   $fh = openhandle(\*STDIN);          # \*STDIN
   $fh = openhandle(*NOTOPEN);         # undef
   $fh = openhandle("scalar");         # undef
 22
Author: brady,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-24 19:29:17

¿Por qué querrías hacer eso? La única razón por la que se me ocurre es cuando estás usando los controladores de archivos de paquetes de estilo antiguo (lo que parece que estás haciendo) y quieres evitar guardar accidentalmente un controlador sobre otro.

Este problema se puede resolver usando nuevos estilos de manejadores de archivos indirectos.

open my $fh, '<', $filename or die "Couldn't open $filename: $!";
 12
Author: Leon Timmermans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-06 13:16:15

Perl proporciona la función fileno exactamente para este propósito.

EDITAR Estoy corregido en el propósito de fileno(). Prefiero la prueba más corta

fileno FILEHANDLE

Sobre

tell FH != -1

 8
Author: converter42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-29 22:47:28

Tell produce una advertencia (también lo hace stat, -s, -e, etc..) con use warnings (- w)

perl -wle '
    open my $fh, "<", "notexists.txt"; 
    print "can stat fh" if tell $fh
'
tell() on closed filehandle $fh at -e line 1.
-1

Las alternativas fileno($fh) y eof($fh) no producen advertencias. Encontré que la mejor alternativa era guardar la salida de open.

 1
Author: CoffeeMonster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-09 21:37:09

¿por Qué te importa si ya está abierto? ¿Estás tratando de captar lecturas simultáneas?

Realmente no necesita preocuparse por cerrar el archivo. O bien no está abierto y el cierre falla porque no tiene nada que cerrar, o el archivo está abierto y el cierre lo libera. De cualquier manera, el archivo no está abierto en ese manejador de archivos. Simplemente cierre el filehandle sin importarle si no está abierto. Estás viendo algo raro ahí?

 0
Author: brian d foy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-19 23:58:28