以最快的方式计算包含数十万个文件的目录中的文件数

时间:2013-07-18 19:58:52

标签: perl unix count directory solaris

在solaris系统中处理大量文件并将其信息存储在数据库中(是的,我知道使用数据库是获取有关我们文件数量的信息的最快方法)。我需要快速监控文件,因为它们在通过系统进行存储在数据库中的过程中。

目前我使用perl脚本将目录读入数组,然后获取数组的大小并将其发送到监视脚本。不幸的是,随着我们系统的发展,这款显示器变得越来越慢。

我正在寻找一种方法,它可以更快地运行,而不是在对所有相关目录执行计数操作后每隔15-20秒暂停和更新。

我相对肯定我的瓶颈是数据操作的读取目录。

我不需要任何有关文件的信息,我不需要大小或文件名,只需要目录中的文件数。

在我的代码中,我不计算隐藏文件或用于保存配置信息的文本文件。如果保留这个功能会很好,但肯定不是强制性的。

我发现了一些使用C代码计算inode的引用或类似的东西,但我在那方面不是很有经验。

我想让这台显示器尽可能实时。

我使用的perl代码如下所示:

opendir (DIR, $currentDir) or die "Cannot open directory: $!";
@files = grep ! m/^\./ && ! /config_file/, readdir DIR; # skip hidden files and config files
closedir(DIR);
$count = @files;

2 个答案:

答案 0 :(得分:9)

您现在所做的只是将整个目录(或多或少)读入内存,只是为了丢弃该内容的计数。通过流式传输目录来避免这种情况:

my $count;
opendir(my $dh, $curDir) or die "opendir($curdir): $!";
while (my $de = readdir($dh)) {
  next if $de =~ /^\./ or $de =~ /config_file/;
  $count++;
}
closedir($dh);

重要的是,不要以任何形式使用glob() glob() will expensively stat() every entry您想要的开销。

现在,根据操作系统功能或文件系统功能(Linux,通过比较,提供inotify),你可能会有更复杂,更轻量级的方法来执行此操作,但是如上所述将dir流式传输与你一样好。 ll便携式。

答案 1 :(得分:-1)

保持简短。

@files = readdir(DIR) - 2;

The -2 is because readdir counts "." and ".." as directory entries.

print @files . " files found\n";
exit;
找到1个文件