2009-05-30 14 views
11

Recibo este error al ejecutar mi script de Perl. Por favor, dime cómo rectificar este error en Perl.¿Cómo resuelvo un error "print() on file filele" en Perl?

print() on closed filehandle MYFILE 

Este es el código que está dando el error:

sub return_error 
{ 
    $DATA= "Sorry this page is corrently being updated...<p>"; 
    $DATA.= "<A href=\"javascript:history.go(-1)\"> Back </A>"; 
    open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 
    print MYFILE $DATA; 
    close(MYFILE); 
    exit; 
} 

espero que ahora estoy más clara.

+1

El título de la publicación debe ser editado. ¡Parece que es un 'error en Perl '! –

+1

sería útil si el mensaje de advertencia de perl "print() en filehand cerrado" también sugiriera verificar que el manejador de archivos se puede abrir o no –

Respuesta

29

Desea realizar alguna acción en MYFILE después de que usted (o el propio intérprete debido a un error) lo haya cerrado.

De acuerdo con el ejemplo del código, el problema podría ser que open realmente no abre el archivo, es posible que el script no tenga permiso para escribir en el archivo.

cambiar su código a la siguiente para ver si había un error:

open(MYFILE, ">", "/home/abc/xrt/sdf/news/top.html") or die "Couldn't open: $!"; 

actualización

ysth señaló que -w no es muy bueno en comprobar si se puede escribir en el fichero , solo 'verifica que uno de los indicadores relevantes en el modo esté establecido'. Además, brian d foy me dijo que el condicional que he usado no es bueno para manejar el error. Así que eliminé el código engañoso. Usa el código de arriba en su lugar.

+1

Preferiría el abierto de tres argumentos: open (MYFILE, '>', $ file) ... – Svante

+0

@Svante: gracias, Brad acaba de corregir que :) –

+0

-w no comprueba que puede escribir en el archivo, comprueba que se haya establecido uno de los indicadores relevantes en el modo. Esto puede producir falsos positivos y falsos negativos. Es mucho mejor tratar de abrirlo para escribir y detectar un error abierto. – ysth

1

En algún lugar de usted es la escritura que va a hacer algo como:

open MYFILE, "> myfile.txt"; 
# do stuff with myfile 
close MYFILE; 
print MYFILE "Some more stuff I want to write to myfile"; 

La última línea generará un error porque MIARCHIVO ha sido cerrado.

actualización

Después de ver su código, parece que el archivo que está intentando escribir en no se puede abrir en el primer lugar. Como otros ya han mencionado, intente hacer algo como:

open MYFILE, "> myfile.txt" or die "Can't open myfile.txt: $!\n" 

Lo cual debería darle algunos comentarios sobre por qué no puede abrir el archivo.

+0

escribí mi código también ............... por favor vea y ayúdeme con la solución –

3

Este:

open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 

En modern Perl, podría escribirse como:

open(my $file_fh, ">", "/home/abc/xrt/sdf/news/top.html") or die($!); 

esta manera se obtiene una variable $ restringida al ámbito de aplicación, no hay una "visita enrrollada" si tiene nombres de archivos raros (por ejemplo, comenzando con ">") y manejo de errores (puede reemplazar el dado con warn o con el código de manejo de errores).

Una vez que cierre $ file_fh o simplemente salga del alcance, ya no podrá imprimir.

12

Parece que la llamada open está fallando. Debe siempre verificar el estado al abrir un identificador de archivo.

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(MYFILE, ">$file") or die "Can't write to file '$file' [$!]\n"; 
print MYFILE $DATA; 
close MYFILE; 

Si la apertura no tiene éxito, el incorporado en la variable $! (a.k.a. $ OS_ERROR) contendrá el mensaje de error de OS-depededant, p. "Permiso denegado"

También es preferible (para las versiones no arcaicas de Perl) para utilizar la forma de tres argumentos de open y filehandles léxicas:

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(my $fh, '>', $file) or die "Can't write to file '$file' [$!]\n"; 
print {$fh} $DATA; 
close $fh; 
+0

Sé que está en PBP, pero no me puedo acostumbrar a la apariencia de 'print {$ fh} $ DATA' para imprimir en Filehandles. Simplemente se ve mal. – Telemachus

3

Compruebe que la abierta trabajaron

if(open(my $FH, ">", "filename") || die("error: $!")) 
{ 
    print $FH "stuff"; 
    close($FH); 
} 
+1

No necesita el constructo if(). Cuando es falso ya mueres. :) –

6

Una solución alternativa a decir or die es utilizar el autodie pragma:

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 

open my $fh, "<", "nsdfkjwefnbwef"; 

print "should never get here (unless you named files weirdly)\n"; 

El código anterior produce el siguiente error (a menos que un archivo llamado nsdfkjwefnbwef existe en el directorio actual):

Can't open 'nsdfkjwefnbwef' for reading: 'No such file or directory' at example.pl line 7 
2

Si utiliza un MIARCHIVO símbolo global como su gestor de archivo, en lugar de un léxico local ($ mi_archivo), invariablemente se encontrará con problemas si su programa es multiproceso, por ejemplo si se está ejecutando a través de mod_perl. Un proceso podría estar cerrando el identificador de archivo mientras otro proceso intenta escribir en él. Usar $ myfile evitará este problema ya que cada instancia tendrá su propia copia local, pero aún se encontrará con problemas en los que un proceso podría sobrescribir los datos que otro está escribiendo. Use flock() para bloquear el archivo mientras escribe en él.

3

Tuve este problema cuando mis archivos se configuraron como READ-SOLAMENTE.

¡Compruebe esto también, antes de darse por vencido! :)

Cuestiones relacionadas