2010-06-15 133 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