Как проверить успешность открытия (файла) в Perl? - PullRequest
13 голосов
/ 08 июля 2010

Следующий (не очень Perl-ish) код

#!/usr/bin/perl

if (! -e "mydir/")
{
  print "directory doesn't exist.\n";
}
open (my $fh, ">", "mydir/file.txt");
if ($fh)
{
  print "file opened.\n";
  print $fh;
  print $fh "some text\n" or die "failed to write to file.\n";
  close ($fh);
}
else
{
  print "failed to open file.\n";
}

производит вывод, такой как этот

directory doesn't exist.
file opened.
failed to write to file.
GLOB(0x...some-hex-digits...)

Почему $ fh не эквивалентноложь после открытого вызова?Поскольку mydir / не существует, я ожидаю, что попытка открытия файла завершится неудачей.

Я получаю аналогичные результаты, если каталог и файл существуют, но файл доступен только для чтения.

Я пробовал это с Perl 5.10.1 на Windows 7 x64 и с Perl 5.10.0 на Fedora-11 Linux.

Я предполагаю, что мой тест дескриптора файла неверен,Я попытался найти это без удачи.Я ожидаю, что это что-то очевидное, но любые советы или ссылки будут высоко оценены.

Спасибо, Роб.

Ответы [ 4 ]

19 голосов
/ 08 июля 2010

$fh не устанавливается на нулевое значение, оно устанавливается на GLOB, как показывает ваш код.Это отличается от того, что возвращает open, поэтому идиома

open(...) or die ... ;

или

unless(open(...)) {
    ...
}
14 голосов
/ 08 июля 2010

open возвращает ненулевое значение при успехе и «ложное» значение при ошибке.Идиома, которую вы ищете:

if (open my $fh, '>', $file) {
    # open was successful
} else {
    # open failed - handle error
}

Если первый аргумент ($fh) не определен (как в данном случае), open инициализирует его в произвольное значение (см.1007 *Symbol::genysm method ) перед попытается открыть файл.Так что $fh будет всегда быть "истиной", даже если вызов open не удастся.

9 голосов
/ 08 июля 2010

С perldoc :

Open возвращает ненулевое значение в случае успеха, в противном случае неопределенное значение.

Часто используемая идиома

open my $fh, '<', $filename or die $!;

Конечно, вы можете сделать что-то еще, чем просто die.

8 голосов
/ 08 июля 2010

В дополнение к объяснениям в других ответах:

Проверьте модуль autodie , который поставляется с perl 5.10.1 и выше (и доступен отдельно от CPAN).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...