在Perl中确定文件大小并不总是有效

时间:2014-10-07 09:21:04

标签: perl file

我正在尝试枚举目录内容并检查那里的文件大小(没有递归)。所以我opendir / readdir通过目录,跳过某些类型的文件(目录等),并使用像my $size = -s "$file_path这样的东西获取当前文件的大小。

但是,我有一个奇怪的情况 - 在一个目录中我无法获得任何文件的大小(包含所有.exe文件)。相同的程序在另一个目录(.txt文件,.pl和类似文件)上运行正常。

如果我将一些.exe文件从第一个目录复制到另一个目录,则其大小已正确确定。

如果我再次在第一个目录上运行该程序,则正确确定复制的.exe的大小,其他所有程序仍然失败。所以这似乎是一些奇怪的缓存问题。

知道为什么会这样吗?

修改:通过-f检查,尺寸检查不起作用的.exe文件不是plain files。但是,如果我只是从那个目录中复制它们,它们就会变成普通文件。然后尺寸检查工作

用于枚举文件的代码部分:

my $dir_handle;
my $dir_entry;


my $retVal = opendir($dir_handle, "$path");
if (!$retVal)
{
    print "Unable to open directory. \n$!";
    exit(0);
}


while ($dir_entry = readdir($dir_handle))
{
    print "Current file: $dir_entry \n";
    next if (! -f $dir_entry);
    my $size_bytes = -s "$dir_entry";

    if ($size_bytes)
    {
        print "Size: $size_bytes \n";
    }

}

closedir($dir_handle);

3 个答案:

答案 0 :(得分:2)

readdir()仅返回文件名 ,并且不包含路径信息 - 因此如果目录与当前工作目录不同,则会失败。

您想要包含路径:

while ($dir_entry = readdir($dir_handle))
{
    print "Current file: $dir_entry \n";
    next if (! -f "$path/$dir_entry");
    my $size_bytes = -s "$path/$dir_entry";

    if ($size_bytes)
    {
        print "Size: $size_bytes \n";
    }
}

(是的,使用Unix风格的路径分隔符在这里工作正常;如果你喜欢转义,可以随意使用\

答案 1 :(得分:1)

readdir仅返回每个目录条目的名称。它不包括正在读取的目录的路径。例如,如果您正在阅读/var/tmp并且该目录包含名为foo的文件,则readdir将返回foo,而不是/var/tmp/foo

要检查目录条目是文件还是获取其大小,您必须提供文件的完整路径名,包括目录部分。除非您在当前目录中专门调用readdir,否则您需要将每个文件名转换为路径名:

while ($dir_entry = readdir($dir_handle))
{
    my $pn = $path . '/' . $dir_entry;
    print "Current file: $pn \n";
    next if (! -f $pn);
    my $size_bytes = -s $pn;
    ...
}

答案 2 :(得分:0)

如前所述,您的错误是在文件操作期间不包括路径信息。

我建议使用Path::Class使您的文件和目录操作跨平台兼容,但也要自动处理这样的问题:

use strict;
use warnings;

use Path::Class;

my $path = '.';

my $dir = dir($path);

for my $child ( $dir->children ) {
    printf "Current file: %s\n", $child->basename;

    next if !-f $child;

    if ( my $size = -s $child ) {
        print "Size: $size\n";
    }
}