如何检查文件句柄是否在Perl中打开?
有没有办法检查文件是否已在Perl中打开? 我想拥有读取文件的权限,因此不需要如何检查文件句柄是否在Perl中打开?,perl,file-io,filehandle,Perl,File Io,Filehandle,有没有办法检查文件是否已在Perl中打开? 我想拥有读取文件的权限,因此不需要flock open(FH, "<$fileName") or die "$!\n" if (<FILE_IS_NOT_ALREADY_OPEN>); # or something like close(FH) if (<FILE_IS_OPEN>); open(FH),请看。我最初在这里写的答案曾经是我们能做的最好的答案,但现在已经过时了。为什么要这样做?我能想到的唯一原因是当
flock
open(FH, "<$fileName") or die "$!\n" if (<FILE_IS_NOT_ALREADY_OPEN>);
# or something like
close(FH) if (<FILE_IS_OPEN>);
open(FH),请看。我最初在这里写的答案曾经是我们能做的最好的答案,但现在已经过时了。为什么要这样做?我能想到的唯一原因是当您使用老式的包文件句柄(您似乎正在这样做)并希望防止意外地将一个句柄保存到另一个句柄
这个问题可以通过使用新样式的间接文件句柄来解决
open my $fh, '<', $filename or die "Couldn't open $filename: $!";
打开我的$fh,Perl提供的函数正是为了这个目的
编辑出于fileno()
的目的,我接受了更正。我更喜欢较短的测试
fileno文件句柄
结束
tell FH!=-1
tell会产生一个警告(stat、-s、-e等也会产生警告),并使用警告
perl-wle'
打开我的$fh,“模块为此提供函数。与之不同,它处理与OS文件句柄无关的perl文件句柄。与之不同,它在未打开的文件句柄上使用时,不会从模块的:
开柄跳频
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
哦,太好了,很高兴知道。谢谢。马特:尝试Perl::Critic以获得更好的样式示例原因:假设您使用open(FH,“-|”)打开了一个文件句柄
。您希望确保分叉过程成功,这需要显式地关闭FH
以适当地设置$!
或$?
。如果没有成功,您希望引发错误;但是,如果其他操作已关闭FH
,则不希望引发错误。另一个用例:您成功地打开了NFSv4挂载的文件系统上的文件句柄,NFS服务器重新启动。有时文件句柄变得无效(EBADF
)。如何检测?嗯……不是真的。它提供fileno以获取系统文件描述符编号。确定文件句柄是否打开是一个副作用(就像它是tell的副作用一样)。而且也不是一个完全可靠的副作用。可能有一个文件句柄打开到文件描述符以外的其他对象,在这种情况下,fileno
明智地返回undef。示例是绑定句柄和打开到标量的句柄。tell(FH)使用关闭的文件句柄生成警告。使用fileno()则不会。这是唯一真正的解决方案,谢谢。tchrist对@daxim links问题的回答相当惊人,但似乎与openhandle不同,因为它会告诉您字符串“STDIN”是打开的(从技术上讲,这似乎是因为你可以将其用于印刷等)现在,你是否真的想要鼓励这种事情是另一个问题;我倾向于看到openhandle拒绝“STDIN”与其说是一个bug,不如说是一个特性。我是从谷歌搜索过来的,我想指出链接到$handle->opened();
WFM.cause错误:…tell()在未打开的文件句柄上…@ekerner从技术上讲不是一个错误,而是一个警告。Scalar::Util(不是最高级别的答案,但应该是)这是最好的方法,因为答案中说明了原因。另请参阅。$fh->Open。eof
有副作用。请参阅其文档。
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