0

合計 2,153,425 項目のディレクトリが存在します (Windows フォルダーのプロパティによる)。いくつかのサブディレクトリ内にある .jpg および .gif 画像ファイルが含まれています。タスクは、各ファイルの名前を照会して関連情報を取得し、別の場所に保存しながら、画像を別の場所に移動することでした。

File::Find を使用したスクリプトは、20462 ファイルで終了しました。好奇心から、1,734,802 のカウントを返す項目をカウントするための小さな再帰関数を作成しました。違いは、フォルダーをカウントせず、 -f テストに合格したファイルのみをカウントしたという事実によって説明できると思います。

問題自体は、ディレクトリをトラバースする代わりに、最初にファイル名を照会することによって別の方法で解決できます。File::Find がすべてのファイルのごく一部で終了した原因は何だったのだろうかと思っています。

データは NTFS ファイル システムに保存されます。

これがスクリプトの要点です。同じ番号を返した process_img() のカウンターだけでスクリプトを再実行したため、DBI のものを含めることは関係ないと思います。

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;
4

1 に答える 1

2

リソースが不足している可能性がありますか?(メモリ、ファイル記述子など...?)。

または、ファンキーなファイル名である可能性があります(再実行することで簡単にテストできますが、10個のファイルを削除します-まったく同じファイルで停止する場合は、そのファイル名が原因です)

メモリフットプリントを追跡できる場合は、メモリリークがあるかどうかがわかります(これについては、メモリリークに関する最近のSOの質問を参照してください)。

そして、Etherが言ったように、コードに貼り付けていれば、一般的な調査のアイデア以上のものを提供できれば幸いです。

アップデート

あなたのコードに基づいて:

  1. 評価がSTDERRに何かを吠えるかどうかを示してください

  2. さらに重要なことに、IO操作はすべてエラーチェックする必要があります。例えば

    copy($something,$other)
        || die "Copy $something to $other died with error: $!\n"; # or print
    # Same for making the directory
    
于 2010-06-15T16:16:20.740 に答える