Как разрешить ошибку "print() при закрытии файла" в Perl?
Я получаю эту ошибку при выполнении моего Perl script. Пожалуйста, скажите мне, как исправить эту ошибку в Perl.
print() on closed filehandle MYFILE
Это код, который дает ошибку:
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;
}
Я надеюсь, что теперь я понятнее.
Ответы
Ответ 1
Вы хотите выполнить какое-либо действие на MYFILE
после того, как вы (или сам интерпретатор из-за ошибки) закрыли его.
В соответствии с вашим примером кода проблема может заключаться в том, что open
действительно не открывает файл, script может не иметь права на запись в файл.
Измените код на следующее, чтобы увидеть, была ли ошибка:
open(MYFILE, ">", "/home/abc/xrt/sdf/news/top.html") or die "Couldn't open: $!";
Update
ysth указал, что -w
не очень хорошо проверяет, можете ли вы писать в файл, он только "проверяет, что один из соответствующих флагов в режиме. Кроме того, brian d foy сказал мне, что условие, которое я использовал, плохо подходит для обработки ошибки. Поэтому я удалил вводящий в заблуждение код. Вместо этого используйте код.
Ответ 2
Похоже, что вызов open
не работает. Вы всегда должны проверять статус при открытии дескриптора файла.
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;
Если open не увенчался успехом, встроенная переменная $! (a.k.a. $OS_ERROR) будет содержать сообщение об ошибке OS-depededant, например. "Разрешение отклонено"
Также предпочтительнее (для неархаичных версий Perl) использовать форму с тремя аргументами open
и лексические дескрипторы файла:
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;
Ответ 3
Альтернативным решением сказать or die
является использование 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";
В приведенном выше коде возникает следующая ошибка (если в текущем каталоге не существует файла с именем nsdfkjwefnbwef):
Can't open 'nsdfkjwefnbwef' for reading: 'No such file or directory' at example.pl line 7
Ответ 4
Это:
open(MYFILE,">/home/abc/xrt/sdf/news/top.html");
В современный Perl, он может быть записан как:
open(my $file_fh, ">", "/home/abc/xrt/sdf/news/top.html") or die($!);
Таким образом вы получаете переменную $, ограниченную областью, нет "фанк-бизнеса", если у вас есть странные имена файлов (например, начиная с " > " ) и обработки ошибок (вы можете заменить die с помощью предупреждения или с кодом обработки ошибок).
Как только вы закрываете $file_fh или просто выходите из области видимости, вы не можете больше печатать на нем.
Ответ 5
Убедитесь, что открытая работа
if(open(my $FH, ">", "filename") || die("error: $!"))
{
print $FH "stuff";
close($FH);
}
Ответ 6
У меня была эта проблема, когда мои файлы были настроены только на READ-ONLY.
Проверьте это, прежде чем сдаваться!:)
Ответ 7
Если вы используете глобальный символ MYFILE в качестве дескриптора файла, а не локальный лексический ($ myfile), вы всегда будете сталкиваться с проблемами, если ваша программа многопоточна, например. если он работает через mod_perl. Один процесс может закрывать дескриптор файла, в то время как другой процесс пытается записать его. Использование $myfile позволит избежать этой проблемы, так как каждый экземпляр будет иметь свою собственную локальную копию, но вы все равно столкнетесь с проблемами, когда один процесс может перезаписать данные, которые другой пишет. Используйте flock(), чтобы заблокировать файл при записи на него.
Ответ 8
Где-то в тебе script вы будете делать что-то вроде:
open MYFILE, "> myfile.txt";
# do stuff with myfile
close MYFILE;
print MYFILE "Some more stuff I want to write to myfile";
Последняя строка выдает ошибку, поскольку MYFILE был закрыт.
Update
После просмотра кода, похоже, файл, который вы пытаетесь записать, не может быть открыт в первую очередь. Как уже упоминалось, попробуйте сделать что-то вроде:
open MYFILE, "> myfile.txt" or die "Can't open myfile.txt: $!\n"
Который должен дать вам некоторые отзывы о том, почему вы не можете открыть файл.