我试图找到一种监视Perl中目录的方法,特别是目录大小,并在检测到目录大小的变化时,执行特定操作。
我遇到的问题是大文件需要大量的时间才能复制到这个目录中,即> 100MB。发生的事情(在Windows中,而不是Unix)是系统为整个文件保留足够的磁盘空间,即使文件仍在进行复制。这会给我带来麻烦,因为我的脚本会尝试对尚未完成复制的文件执行操作。我可以通过'du'轻松检测Unix中的目录大小更改,但Windows中的'du'行为方式不同。
在Perl中是否有任何准确的方法来检测目录大小的变化?
编辑:有些要点澄清: - 我的Perl脚本仅监视特定目录,并在检测到新文件或新目录时,对此新文件或目录执行操作。它没有复制任何文件;网络上的用户将文件复制到我正在监控的目录中。 - 出现(复制,未移动)新文件或目录非常大(> 100MB,但通常为几GB)并且我的程序在此副本完成之前触发时出现问题 - 在Unix中,我很容易'du'看到有问题的文件/目录的大小正在增加,并采取适当的措施 - 在Windows中,大小是静态的,所以我无法检测到这种变化 - opendir / readdir / closedir不可行,因为出现的一些目录可能包含数千个文件,我想避免开销
理想情况下,我希望我的程序在更改时触发,但我不知道如何执行此操作。截至目前,它一直等到检测到变化。文件/目录大小的变化不在我的控制范围内。
答案 0 :(得分:3)
您似乎正在解决基础问题而不是解决它 - 您的程序在完成复制文件时没有正确发送通知。为什么不这样做而不是使用特定于操作系统的机制来尝试间接确定操作何时完成?
答案 1 :(得分:3)
您可以使用Linux::Inotify2或Win32::ChangeNotify来检测目录/文件更改。
编辑:File::ChangeNotify似乎是一个更好的选择(跨平台和Catalyst使用)
答案 2 :(得分:1)
据我了解,您正在使用数千个文件轮询目录。当您看到新文件时,会对该文件执行操作。如果文件正在使用或仍在被复制,这会导致问题,对吗?
可能有几种解决方案:
1)使用flock检测该文件是否仍被其他进程使用(测试它是否在您的操作系统,文件系统和Perl版本上正常运行)。
2)在Windows上使用LockFile调用。如果失败,则OS或其他进程正在使用该文件。
3)将轮询间隔更改为服务器上的非忙碌时间,并在流程完成时使目录脱机。
答案 3 :(得分:0)
评估目录的大小是除了最缺乏经验的Perl程序员应该能够做的事情。如果您知道:
,可以在15行代码中编写自己的du
可移植版本
glob
或opendir / readdir / closedir
来遍历目录中的文件-f file
,-d file
等)stat
函数或文件大小运算符-s file
答案 4 :(得分: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
}
}
} );
如果你需要深入到一个级别,只需要达到你需要的任何级别。完成此操作并找到新文件后,您可以触发应用程序在文件上执行所需操作。