最近携帯電話に写真をバックアップするときに、手動で行うのが少し面倒に感じたので、それを自動的に行うスクリプトを書きたいと思いました。一部の写真は以前にバックアップされているため、重複判定操作が必要です。
メイン関数は、次のように copyFiles() 関数に実装されています:
def copyFiles(src, dst): srcFiles = os.listdir(src) dstFiles = dict(map(lambda x:[x, ''], os.listdir(dst))) filesCopiedNum = 0 # 对源文件夹中的每个文件若不存在于目的文件夹则复制 for file in srcFiles: src_path = os.path.join(src, file) dst_path = os.path.join(dst, file) # 若源路径为文件夹,若存在于目标文件夹,则递归调用本函数;否则先创建再递归。 if os.path.isdir(src_path): if not os.path.isdir(dst_path): os.makedirs(dst_path) filesCopiedNum += copyFiles(src_path, dst_path) # 若源路径为文件,不重复则复制,否则无操作。 elif os.path.isfile(src_path): if not dstFiles.has_key(file): shutil.copyfile(src_path, dst_path) filesCopiedNum += 1 return filesCopiedNum
ここでは、最初に os.listdir() 関数を使用して、ソース フォルダー src とターゲット フォルダー dst を走査し、2 つのファイル リストを取得します。 Heavy オペレーションを判定する必要があるため、dst ファイルリストでクエリオペレーションを実行する必要があります。リストのクエリ効率は高くなく、辞書はハッシュ テーブルであるためクエリ効率が高いため、対象ファイルのリストをキーのみで値を含まない辞書に変換しました。
dstFiles = dict(map( lambda x:[x , ''], os.listdir(dst)))
次に、パスがフォルダーの場合は、まずフォルダーがターゲット パスに存在するかどうかを確認します。存在する場合は、まず新しいパスを作成します。次に、この関数を再帰的に呼び出します。本当は存在しない場合はshutil.copytree()関数を呼び出す方が効率的ですが、ここではコピーしたファイル数を計算する必要があるためこの関数は呼びません。
パスがファイルの場合、まず対象フォルダーにファイルが存在するかどうかを確認します。存在しない場合はコピーしてください。
このスクリプトは主にモバイル フォト アルバムを PC に同期するために書かれているため、ファイル名を簡単に決定するだけです。名前が異なるが同じファイルを判定したい場合は、ここでは説明しませんが、続けて md5 値を判定できます。
りー