使用Perl如何检查文件是否已打开?

6

如何确定一个文件是否正在被打开或使用?(我说的是文件而不是Perl文件句柄。)

请注意,我正在寻找通用的Perl解决方案,而不是特定于操作系统的解决方案。至少,我希望能够在Windows和GNU/Linux系统上运行。


如何检查Perl中文件句柄是否打开 - cppcoder
@cppcoder:你所提到的问题似乎是关于文件句柄的打开。而我在这个问题中谈论的是文件。 - Sam
2
POSIX没有提供任何方法来实现这一点。因此,鉴于当前可用的便携式操作系统接口,没有可移植的解决方案。您必须设计一些更高级别的方法,为打开位提供单一访问点。这就像锁定文件一样。 - tchrist
@tchrist,如果您将该评论转换为答案,我想我会接受您的回答。 - Sam
在Windows上有什么解决方案?如果它是特定于Windows的,我也不介意。 - Helen Craigman
@HelenCraigman,我不知道;我正在寻找跨平台的东西。猜测你可能可以使用Windows API。请参考这篇Stack Overflow帖子中的一种可能的方法。我认为最好你将此作为一个新的Stack Overflow问题发布,因为这个问题并不是在寻求Windows特定的解决方案。 - Sam
8个回答

5

POSIX没有提供任何方法来做到这一点。因此,鉴于当前可用的便携式操作系统接口,没有可移植解决方案。

你需要设计一些更高级的方法,以提供单个访问点来打开这些位。就像锁定文件一样。


0
请看以下代码片段(仅适用于Linux/Unix,您没有告诉我们您运行的操作系统):
一行代码:
perl -e 'my $file = $ARGV[0]; print "file $file is opened" if `lsof $file`;' FILE

在脚本中:
#!/usr/bin/env perl -w

use strict;

my $file = $ARGV[0];
print "file $file is opened\n" if `lsof $file`;

运行它:

./script.pl FILENAME

这在基于Unix的系统上可能是一个好方法。但是,我正在使用Windows。一种不依赖于操作系统的通用解决方案会更好。 - Sam
有一个 Perl 模块:http://search.cpan.org/~marcb/Unix-Lsof-0.0.9/lib/Unix/Lsof.pm,但只能在 Unix 和类 Unix 系统上运行。也许可以通过使用 cygwin 来解决这个问题。 - Gilles Quénot
1
@flesk:你能提供有关该模块的更多信息吗?它是否也只适用于Linux?如果不是,你能否提供一个使用它来解决这个问题的例子? - Sam
1
在OpenBSD上,使用的是fstat而不是lsof - tchrist

-1

我知道已经有一段时间了,但对于Windows来说,我在检测文件是否正在被写入方面运气不错,只需尝试锁定文件(没有花哨的东西 - 只需打开以进行读取,使用Perl内部flock并关闭文件)。这似乎甚至可以在网络文件上工作。我不确定这是否适用于Linux(它可能适用于写入),也不知道它是否可以检测其他文件读取器。


-1
尝试重命名文件,如果文件正在使用中,则会失败。

-1

尝试使用Scalar::Util

Scalar::Util模块提供了openhandle()函数。与fileno()不同,它处理与OS文件句柄无关的Perl文件句柄。与tell()不同,当在未打开的文件句柄上使用时,它不会产生警告。从该模块的文档中可以看到:

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

我看了一下那个函数,但似乎并没有解决我的问题。不过,有可能是因为我不知道如何使用该函数来完成我所要求的操作。 - Sam
是的,抱歉,答案错了。我想你需要在Win32 API中寻找特定于Windows的文件打开函数。 - Sly

-1

我阅读了很多帖子,但没有找到我要寻找的解决方案。在我的情况下,我有一个for循环创建和关闭大量文件。我想检查我创建的文件处理器是否打开。以下是如何实现:

use IO::Handle;

if (something matches create a file)
{
  open( $signoff_report_html, '>', "$val21");
}
elsif ( ... )
{
  #keep doing amazing stuff
}
else
{
   if ($signoff_report_html->opened()) 
   {    
      #file is ok
      print "File is opened and ready\n";       
  }
  else 
  {
      print "File was closed ... ";
  }
}

-1

试试这个

use strict;
open(IN, ">test");
print IN "Hello";
close(IN);
if(fileno(IN) == undef )
{
    print "File is CLOSED\n";
}

我在询问文件而不是文件句柄。 - Sam

-2

我知道你不想打开文件句柄,但在我看来这可能是最简单的方法:

open my $myfh, '<', $my_file or die "Couldn't open $my_file: $!";

我认为即使文件已经在其他地方打开,你通常也可以以只读模式打开它们。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接