How do you check the success of open (file) in Perl?

血红的双手。 提交于 2021-02-07 11:32:33

问题


The following (not very Perl-ish) code

#!/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";
}

produces the output such as this

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

Why is $fh not equivalent to false following the open call? As mydir/ does not exist, I'd expect the attempt to open the file to fail.

I get similar results if the directory and file exist, but the file is read-only.

I've tried this with Perl 5.10.1 on Windows 7 x64, and with Perl 5.10.0 on Fedora-11 Linux.

I'm guessing my file handle test is wrong. I've tried Googling this without luck. I expect it's something obvious, but any hints or links would be much appreciated.

Thanks, Rob.


回答1:


$fh isn't being set to a zero-ish value, it is being set to a GLOB as your code shows. This is different from what open returns which is why the idiom is

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

or

unless(open(...)) {
    ...
}



回答2:


open returns a non-zero value on success, and a "false" value on failure. The idiom you are looking for is

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

If the first argument ($fh) is undefined (as it is in this case), open will initialize it to some arbitrary value (see the Symbol::genysm method) before it attempts to open the file. So $fh will always be "true" even if the open call fails.




回答3:


From perldoc:

Open returns nonzero on success, the undefined value otherwise.

An often used idiom is

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

Of course you can do something else than simply die.




回答4:


In addition to the explanations in the other answers:

Check out the autodie module which comes with perl 5.10.1 and up (and is available separately from CPAN).




回答5:


Just a warning

unless (open my $fh , '<', 'foobar') {
    print "Error Opening";
}
print $fh, "Some Text";

will fail, as $fh is defined in unless context, not outside/after it. So only the if contruct from above will work.



来源:https://stackoverflow.com/questions/3203860/how-do-you-check-the-success-of-open-file-in-perl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!