一个目录共有 2,153,425 个项目(根据 Windows 文件夹属性)。它包含位于几个子目录中的 .jpg 和 .gif 图像文件。任务是将图像移动到不同的位置,同时查询每个文件的名称以检索一些相关信息并将其存储在其他位置。
使用 File::Find 的脚本在 20462 个文件处完成。出于好奇,我编写了一个小递归函数来计算返回计数为 1,734,802 的项目。我想差异可以通过它不计算文件夹的事实来解释,只有通过 -f 测试的文件。
问题本身可以通过首先查询文件名而不是遍历目录来以不同的方式解决。我只是想知道是什么导致 File::Find 在所有文件的一小部分完成。
数据存储在 NTFS 文件系统上。
这是脚本的主要内容;我不认为包含 DBI 的东西是相关的,因为我只用 process_img() 中的一个计数器重新运行了脚本,它返回了相同的数字。
find(\&process_img, $path_from);
sub process_img {
eval {
return if ($_ eq "." or $_ eq "..");
## Omitted querying and composing new paths for brevity.
make_path("$path_to\\img\\$dir_area\\$dir_address\\$type");
copy($File::Find::name, "$path_to\\img\\$dir_area\\$dir_address\\$type\\$new_name");
};
if ($@) { print STDERR "eval barks: $@\n"; return }
}
编辑:
eval 就 BDI 错误咆哮了几次:
DBD::CSV::db do failed: Mismatched single quote before:
'INSERT INTO img_info (path, type, floorplan, legacy_id)
VALUES (
?0?building?1?0?2?19867'
)' at C:/perl/site/lib/SQL/Statement.pm line 77
[for Statement "
INSERT INTO img_info (path, type, floorplan, legacy_id)
VALUES (
'wal/15 Broad Street/building/nyc-Wall-St--South-St--Seaport-condo-elevator- building-52201501.jpg',
'building',
'0',
'19867'
)
"]
我认为这是由于“St”和“South”之间的双破折号。没有报告其他性质的错误。
这是我用来计算文件的另一种方法:
count_images($path_from);
sub count_images {
my $path = shift;
opendir my $images, $path or die "died opening $path";
while (my $item = readdir $images) {
next if $item eq '.' or $item eq '..';
$img_counter++ && next if -f "$path/$item";
count_images("$path/$item") if -d "$path/$item";
}
closedir $images or die "died closing $path";
}
print $img_counter;