Почему File :: Find завершил полный обход большого каталога? - PullRequest
0 голосов
/ 15 июня 2010

Каталог существует в общей сложности с 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 }
}

EDIT:

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;

1 Ответ

2 голосов
/ 15 июня 2010

Возможно, закончились ресурсы? (память, файловые дескрипторы и т.д ...?).

или это может быть какое-то непонятное имя файла (его легко проверить, выполнив заново, но удалив 10 файлов - если оно останавливается на том же самом файле, виновником является это имя файла)

Если вы можете отследить след памяти, это сообщит вам, если у вас есть утечка памяти (см. Недавний вопрос SO об утечках памяти, чтобы помочь с этим).

И, как сказал Эфир, мы могли бы предложить больше, чем просто следственную идею, если бы вы вставили ее в код.

UPDATE

На основании одного вашего кода:

  1. Пожалуйста, укажите, лает ли Эвал что-нибудь для STDERR

  2. Что еще более важно, любые операции ввода-вывода должны проверяться на ошибки. Э.Г.

    copy($something,$other)
        || die "Copy $something to $other died with error: $!\n"; # or print
    # Same for making the directory
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...