How can I check if a filehandle is open in Perl? [

2020-03-01 03:47发布

Is there a way to check if a file is already open in Perl? I want to have a read file access, so don't require flock.

 open(FH, "<$fileName") or die "$!\n" if (<FILE_IS_NOT_ALREADY_OPEN>);
 #  or something like
 close(FH) if (<FILE_IS_OPEN>);

5条回答
来,给爷笑一个
2楼-- · 2020-03-01 04:22

The Scalar::Util module provides the openhandle() function for this. Unlike fileno(), it handles perl filehandles which aren't associated with OS filehandles. Unlike tell(), it doesn't produce warnings when used on an unopened filehandle From the module's documentation:

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
查看更多
放我归山
3楼-- · 2020-03-01 04:27

Why would you want to do that? The only reason I can think of is when you're using old style package filehandles (which you seem to be doing) and want to prevent accidentally saving one handle over another.

That issue can be resolved by using new style indirect filehandles.

open my $fh, '<', $filename or die "Couldn't open $filename: $!";
查看更多
ゆ 、 Hurt°
4楼-- · 2020-03-01 04:28

Tell produces a warning (so does stat, -s, -e, etc..) with 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

The alternatives fileno($fh) and eof($fh) do not produce warnings. I found the best alternative was to save the output from open.

查看更多
成全新的幸福
5楼-- · 2020-03-01 04:32

Please see the answer regarding openhandle() from Scalar::Util. The answer I originally wrote here was once the best we could do, but it's now badly outdated.

查看更多
▲ chillily
6楼-- · 2020-03-01 04:48

Perl provides the fileno function for exactly this purpose.

EDIT I stand corrected on the purpose of fileno(). I do prefer the shorter test

fileno FILEHANDLE

over

tell FH != -1

查看更多
登录 后发表回答