2010-06-15 87 views
0

一个目录共有2,153,425个项目(根据Windows文件夹属性)。它包含位于几个子目录内的.jpg和.gif图像文件。其任务是在查询每个文件的名称以检索一些相关信息并将其存储在别处时将图像移动到不同的位置。为什么File :: Find完成不了完全遍历大目录?

使用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 ([email protected]) { print STDERR "eval barks: [email protected]\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' 
     ) 
"] 

我认为这是由于 '圣' 和 '南方' 之间的双横线。没有报告其他性质的错误。

这里是我用来记录文件的另一种方法:

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; 
+1

没有看到一些代码,这是任何人的猜测。 – Ether 2010-06-15 16:13:22

回答

2

它可能已经耗尽资源? (内存,文件描述符等?)。

或者也有可能是一些时髦的文件名(很容易通过重新运行一次,但除去10个文件,以测试 - 如果它停在完全相同的文件,该文件名是罪魁祸首)

如果你可以跟踪内存占用,这会告诉你,如果你有内存泄漏(见最近SO问题的内存泄漏,以帮助这一点)。如Ether所说,我们可以提供希望超过一般调查的想法,如果你粘贴了代码。

UPDATE

基于一个代码:

  1. 请注明EVAL是否树皮什么STDERR

  2. 更重要的是,任何IO操作需错误检查。例如。

    copy($something,$other) 
        || die "Copy $something to $other died with error: $!\n"; # or print 
    # Same for making the directory