【问题标题】:How can I check if a filehandle is open in Perl? [duplicate]如何检查文件句柄是否在 Perl 中打开? [复制]
【发布时间】:2009-02-06 13:04:36
【问题描述】:

有没有办法检查文件是否已经在 Perl 中打开? 我想要读取文件的权限,所以不需要flock

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

【问题讨论】:

    标签: perl file-io filehandle


    【解决方案1】:

    请参阅answer regarding openhandle() from Scalar::Util。我最初在这里写的答案曾经是我们能做的最好的,但现在已经严重过时了。

    【讨论】:

    • 导致错误:...tell() on unopened filehandle ...
    • @ekerner 从技术上讲不是错误,而是警告。
    • Scalar::Util (不是最受好评的答案,但应该是)是最好的方法,因为该答案中说明了原因。
    • 另见perldoc.pl/IO::Handle。 $fh->已打开。
    【解决方案2】:

    Scalar::Util 模块为此提供了openhandle() 函数。与fileno() 不同,它处理与操作系统文件句柄无关的perl 文件句柄。与tell() 不同,它在用于未打开的文件句柄时不会产生警告来自模块的documentation

    打开句柄 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
    

    【讨论】:

    • 这是唯一真正的解决方案,谢谢。
    • tchrist 对@daxim links 问题的回答相当壮观,但似乎与 openhandle 不同,它会告诉您字符串“STDIN”是打开的(从技术上讲,它似乎是,因为您可以将其用于打印等。)现在您是否真的想要鼓励这种事情是另一个问题;我倾向于将 openhandle 拒绝“STDIN”视为一个特性而不是一个错误。
    • 我通过 Google 搜索来到这里,并想指出链接到 $handle-&gt;opened(); WFM。
    【解决方案3】:

    您为什么要这样做?我能想到的唯一原因是当您使用旧样式的包文件句柄(您似乎正在这样做)并希望防止意外地将一个句柄保存在另一个句柄上时。

    这个问题可以通过使用新的间接文件句柄来解决。

    open my $fh, '<', $filename or die "Couldn't open $filename: $!";
    

    【讨论】:

    • 哦,太好了,很高兴知道。谢谢。
    • matt:尝试 Perl::Critic 以获得更好的风格
    • 示例原因:假设您使用open(FH, "-|") 打开了一个文件句柄。您要确保分叉进程成功,这需要明确地 close FH 适当地设置 $!$?。如果它没有成功,你想引发一个错误;但是,如果其他东西已经关闭FH,您不想引发错误。
    • 另一个用例:您成功打开了 NFSv4 挂载文件系统上的文件句柄,并且 NFS 服务器重新启动。有时文件句柄会变得无效 (EBADF)。如何检测?
    【解决方案4】:

    Perl 正是为此目的提供了fileno 函数。

    编辑我坚持fileno() 的目的。我确实更喜欢较短的测试

    fileno FILEHANDLE

    结束

    tell FH != -1

    【讨论】:

    • 嗯...不是真的。它提供 fileno 用于获取系统文件描述符编号。确定文件句柄是否打开是一个副作用(就像它是 tell 的副作用一样)。
    • 也不是完全可靠的副作用。可能有一个对文件描述符以外的东西开放的文件句柄,在这种情况下fileno 明智地返回 undef。示例是绑定句柄和打开到标量的句柄。
    • tell(FH) 产生带有关闭文件句柄的警告。使用 fileno() 不会。
    【解决方案5】:

    Tell 使用use warnings (-w) 生成警告(stat、-s、-e 等也是如此)

    perl -wle '
        open my $fh, "<", "notexists.txt"; 
        print "can stat fh" if tell $fh
    '
    tell() on closed filehandle $fh at -e line 1.
    -1
    

    fileno($fh)eof($fh) 的替代选项不会产生警告。 我发现最好的选择是保存 open 的输出。

    【讨论】:

    • eof 有副作用。查看它的文档。
    猜你喜欢
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 2012-06-04
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2015-11-28
    相关资源
    最近更新 更多