3

我试图找到一种在 Perl 中监视目录的方法,特别是目录的大小,并在检测到目录大小的变化时,执行特定的操作。
我遇到的问题是需要大量时间才能复制到此目录的大文件,即 > 100MB。发生的事情(在 Windows 中,而不是 Unix 中)是系统为整个文件保留了足够的磁盘空间,即使文件仍在复制中。这给我带来了问题,因为我的脚本将尝试对尚未完成复制的文件执行操作。我可以通过“du”轻松检测 Unix 中的目录大小变化,但 Windows 中的“du”的行为方式不同。

是否有任何准确的方法可以检测 Perl 中的目录大小变化?

编辑:需要澄清的几点: - 我的 Perl 脚本仅监视特定目录,并在检测到新文件或新目录时,对这个新文件或目录执行操作。它没有复制任何文件;网络上的用户会将文件复制到我正在监视的目录中。- 当出现非常大(> 100MB,但通常为几 GB)的新文件或目录(已复制,未移动)并且我的程序在此复制完成之前触发时,就会出现问题 - 在 Unix 中,我可以轻松地“du”看到相关文件/目录的大小正在增长,并采取适当的措施 - 在 Windows 中,大小是静态的,所以我无法检测到这种变化 - opendir/readdir/closedir 不是可行,因为出现的一些目录可能包含数千个文件,我想避免

理想情况下,我希望我的程序在更改时触发,但我不确定如何执行此操作。截至目前,它忙于等待,直到检测到更改。文件/目录大小的变化不在我的控制范围内。

4

5 回答 5

3

您可以使用Linux::Inotify2Win32::ChangeNotify来检测目录/文件更改。

编辑:File::ChangeNotify似乎是一个更好的选择(跨平台并由Catalyst使用)

于 2010-06-08T09:16:01.780 回答
3

您似乎正在解决根本问题而不是解决它 - 您的程序在完成复制文件时没有正确发送通知。为什么不这样做,而不是使用特定于操作系统的机制来尝试间接确定操作何时完成?

于 2010-06-07T17:36:34.280 回答
1

据我了解,您正在轮询包含数千个文件的目录。当您看到一个新文件时,会对该文件执行一项操作。如果文件正在使用或仍在复制,这会导致问题,对吗?

可能有几种解决方案:

1) 使用flock来检测文件是否仍在被另一个进程使用(测试它是否在您的操作系统、文件系统和Perl 版本上正常工作)。

2) 在 Windows 上使用 LockFile 调用。如果失败,则操作系统或其他进程正在使用该文件。

3) 将轮询间隔更改为服务器上的非繁忙时间,并在进程完成时使目录脱机。

于 2010-06-08T02:25:56.673 回答
0

评估一个目录的大小是几乎没有经验的 Perl 程序员应该能够做的事情。du如果您了解以下内容,您可以编写自己的可移植版本,只需15 行代码:

  1. 或者遍历目录中的glob文件opendir / readdir / closedir
  2. 用于区分常规文件和目录名称的文件测试运算符(-f file、、等)-d file
  3. 获取文件大小的stat函数或文件大小运算符-s file
于 2010-06-07T18:14:54.020 回答
0

有一个名为 File::Monitor 的不错的模块,它将检测新文件、已删除文件、大小更改以及任何其他可以使用 stat 完成的属性。然后它将为您输出文件。

http://metacpan.org/pod/File::Monitor

您设置基线扫描,然后为您要查找的每个项目设置回调,因此您可以通过以下方式查看新更改

$monitor->watch( {
    name        => 'somedir',
    recurse     => 1,
    callback    => {
        files_created => sub {
            my ($name, $event, $change) = @_;
            # Do stuff
        }
    }
} );

如果您需要更深一层,只需执行您需要的任何级别即可。完成此操作并找到新文件后,您可以触发您的应用程序对文件执行您想要的操作。

于 2010-08-09T01:58:51.810 回答