0

こんばんは。JPEG 画像から EXIF データを収集し、Python v2.x を使用して MySQL データベースに保存するコードの開発を検討していますたとえば、ルート > サブルート > サブルート 1 に 200 個の JPEG が格納され、ルート > サブルート > サブルート 2 にさらに 100 個の JPEG が格納されます。すべての画像が識別されると、MySQL テーブルに追加される前にそれらがスキャンされ、それぞれの EXIF データが抽象化されます。

現時点では計画段階ですが、再帰検索を実行する最も効率的でPython的な方法は何でしょうか? ルート ディレクトリをスキャンし、新しく特定されたサブディレクトリをリストに追加してから、すべてのディレクトリの合計リストが得られるまで、リスト内のすべてのサブディレクトリ パスをスキャンしてさらにサブディレクトリを探します。私見ですが、これは不器用な方法であり、少し反復的であるように思われるため、この機能を実行するOOPの方法がもっとあると思います。

同様に、MySQL テーブルに新しい情報を追加したいだけなので、エントリが既に存在するかどうかを確認する最も効率的な方法は何でしょうか? テーブル内のファイル名と JPEG ファイル名の両方がその MD5 ハッシュ値になります。コードの先頭でテーブルをスキャンし、すべてのファイル名をセットに配置することを検討していたので、新しい JPEG をスキャンする前に、エントリがセットに既に存在する場合、EXIF を抽出して次に進む必要はありません。次の写真。しかし、これは効率的な方法ですか、それとも新しい画像が検出されたときに MySQL テーブルをスキャンする方がよいでしょうか? set メソッドが最も効率的であると予想されますが、テーブルには最終的に数千万のエントリが含まれる可能性があるため、これらのエントリのファイル名をセット (揮発性メモリ) に追加することは最善の方法ではない可能性があります。

ありがとうございます。

4

1 に答える 1

2

ディレクトリのすべてのファイルをスキャンする関数を作成するだけです。jpegの場合は、結果のリストにjpegのフルパス名を追加します。ディレクトリの場合は、新しく検出されたディレクトリを引数として関数をすぐに呼び出します。別の種類のファイルの場合は、何もしません。これは、古典的な再帰分割統治戦略です。ディレクトリパスにループがある場合、たとえばシンボリックリンクがある場合は壊れます。これが危険な場合は、「実際の」非リンクを見つけて同じディレクトリを2回トラバースしないようにする必要があります。 -各ディレクトリのシンボリックリンクされたパスとそれを記録します。

重複エントリを回避する方法は難しい問題であり、まったく同じ内容の2つの異なる名前のファイルに耐えられるかどうか(および、シンボリックリンクまたはマルチハードリンクファイルのエッジケースも考慮する)、新しいファイルを検討する必要があります。スキャンしているディレクトリに表示され、そのプロセスを制御できるかどうか。それをスピードアップするための1つのアイデアは、os.path.getmtime()を使用することです。。ディレクトリトラバーサルプロセスを開始した瞬間を記録します。次回は、再帰的トラバーサルプロセスで、記録された時間よりもmtimeが古いjpegファイルを無視するようにします。プロセスの開始時刻と終了時刻の間に変更されたファイルが記録される場合とされない場合があるため、これが追跡する唯一の方法ではありません。そのため、データベースでそれらの記録を確認する必要があります(たとえば、フルパスを使用して許容できない重複の種類に応じて、ファイル情報のハッシュまたはデータ自体のハッシュ)が、ヒューリスティックとして使用すると、プロセスが大幅に高速化されます。

理論的には、すべてのファイル名(おそらくファイル名ではなくパス)をデータベースからメモリにロードして比較を高速化できますが、テーブルが非常に大きくなる危険性がある場合は、その情報をデータベースに残しておくことをお勧めします。たとえば、ファイル名からハッシュを作成し、それをUNIQUE制約を使用してデータベースに追加するだけで、データベースは重複するエントリをすべて拒否し、例外をキャッチして続行できます。前述のヒューリスティックチェックファイルmtimeを使用すれば、これは遅くなりません。

アプリケーションにとって重要な場合は、ファイルが変更されるだけで、新しく作成されない可能性があることを考慮してください。

于 2012-05-05T18:09:56.580 に答える