确定Windows上的Perl中是否正在使用文件

Ric*_*ard 5 windows testing perl winapi file

我正在编写一些Perl,它可以在Windows Media Center上录制电视节目,并根据特定条件移动/重命名/删除它们.

由于Perl运行相当频繁,我想清楚地确定文件是否正在使用(换句话说,节目正在被录制过程中),所以我可以避免对它做任何事情.

我当前的方法查看文件的状态(使用"stat")并在5秒后再次比较它,如下所示:

sub file_in_use
{
  my $file = shift;

  my @before = stat($file);
  sleep 5;
  my @after = stat($file);

  return 0 if ($before ~~ $after);
  return 1;
 }
Run Code Online (Sandbox Code Playgroud)

它似乎有效,但我很有意思,可能有更好,更清洁的方法来做到这一点.

你能给些建议么?

Gre*_*con 8

如果录制过程锁定文件,您可以尝试以读写模式打开它,看看它是否因为ERROR_SHARING_VIOLATIONas GetLastError(通过Perl的$^E特殊变量访问)而失败.

例如:

#! /usr/bin/perl

use warnings;
use strict;

sub usage { "Usage: $0 file ..\n" }

die usage unless @ARGV;

foreach my $path (@ARGV) {
  print "$path: ";

  if (open my $fh, "+<", $path) {
    print "available\n";
    close $fh;
  }
  else {
    print $^E == 0x20 ? "in use by another process\n" : "$!\n";
  }
}
Run Code Online (Sandbox Code Playgroud)

Dir100526Lt.pdfAdobe读者打开的示例输出:

C:\Users\Greg\Downloads>check-lock.pl Dir100526Lt.pdf setup.exe
Dir100526Lt.pdf: in use by another process
setup.exe: available

请注意,每当您首次测试条件然后根据该测试的结果进行操作时,您就会创建竞争条件.似乎最糟糕的是,这可能会让你在应用程序中咬住以下不幸的序列:

  1. 如上所述测试视频的可用性
  2. 回答:可用!
  3. 与此同时,录音机启动并锁定视频
  4. 回到您的程序中,您尝试移动视频,但它会因共享违规而失败