Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Perl中检测目录大小的变化_Perl_Directory_Size_Detection - Fatal编程技术网

如何在Perl中检测目录大小的变化

如何在Perl中检测目录大小的变化,perl,directory,size,detection,Perl,Directory,Size,Detection,我试图找到一种在Perl中监视目录的方法,特别是目录的大小,并在检测到目录大小的变化时执行特定的操作。 我遇到的问题是,大文件需要相当长的时间才能复制到此目录,即大于100MB。发生的情况(在Windows而不是Unix中)是系统为整个文件保留了足够的磁盘空间,即使文件仍在复制中。这会给我带来问题,因为我的脚本将尝试对此尚未完成复制的文件执行操作。我可以通过'du'在Unix中很容易地检测到目录大小的变化,但是Windows中的'du'的行为方式不同 在Perl中有没有准确的方法来检测目录大小的

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

在Perl中有没有准确的方法来检测目录大小的变化

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


理想情况下,我希望我的程序在发生变化时被触发,但我不知道如何做到这一点。从现在开始,它一直在等待,直到检测到变化。文件/目录大小的更改不在我的控制范围内。

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

评估目录的大小是除了最缺乏经验的Perl程序员之外的所有人都应该能够做的事情。如果您了解以下内容,您可以用15行代码编写自己的便携式版本的
du

  • glob
    opendir/readdir/closedir
    迭代目录中的文件
  • filetest操作符(
    -f file
    -d file
    等)用于区分常规文件和目录名
  • stat
    函数或文件大小操作符
    -s file
    获取文件大小

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

    可能有几种解决方案:

    1) 用于检测文件是否仍在被其他进程使用(测试它是否在操作系统、文件系统和Perl版本上正常工作)

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

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

    您可以使用或检测目录/文件更改


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

    有一个很好的模块叫做File::Monitor,它将检测新文件、删除的文件、大小的变化以及任何其他可以用stat完成的属性。然后它将为您输出文件

    您设置了一个基线扫描,然后为您要查找的每个项目设置一个回调,这样您就可以通过

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

    如果你需要比一个层次更深入的话,你只需要达到你需要的任何层次。完成此操作并找到新文件后,您可以触发应用程序对文件执行所需操作。

    信号文件(或其他带外通信方法)是解决方法。抱歉,没有澄清。问题是我的程序没有进行复制;它只监视特定目录中文件或目录大小的更改。复制将由外部源完成,即网络上的随机用户。这不是比复制
    du
    更大的延迟问题吗?我想他是在声明(不是很清楚)在复制文件结束之前调用了他的实用程序,因为他正在轮询目录的大小。@drewk可能是这样。有时很难决定是否回答本该问的问题,而不是回答被问的问题。非常抱歉没有提前澄清。我想到了opendir/readdir/closedir,但问题是我正在监视的文件/目录包含数千个文件,打开每个文件的开销是我试图避免的。我将尝试编辑我的原始问题,使其更具体。@materialmage-您不需要打开它们。使用
    stat
    -s
    获取文件大小。此建议不可缩放。您需要像Linux::Inotify2这样的东西来确保不会错过任何状态更改。glob和readdir速度太慢,stat也太不准确。请澄清一下:您是否正在轮询目录的大小,以查看文件大小的总体变化?文件的更改是否由您控制?您能否更改程序的逻辑,以便在更改或连续轮询时调用您的实用程序?