首頁  >  文章  >  後端開發  >  Python - 檔案拷貝

Python - 檔案拷貝

高洛峰
高洛峰原創
2016-10-19 15:21:491185瀏覽

最近在備份手機上的照片的時候,純手工操作覺得有些麻煩,就想寫個腳本自動進行。因為備份的時候有些照片以前備份過了,所以需要有判重操作。

主要功能在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,得到兩個文件列表,但由於我需要判重操作,因此需要在dst檔案清單中進行查詢操作。由於列表的查詢效率不高,而字典是一個雜湊表,查詢效率較高,因此我將目標檔案列表轉換成一個只有鍵沒有值的字典:

dstFiles = dict(map(lambda x:[x , ''], os.listdir(dst)))

然後我遍歷源文件列表,若該路徑是一個文件夾,先判斷該文件夾在目標路徑中是否存在,若不存在,則先創建一個新路徑。然後遞歸呼叫本函數。其實不存在的時候更有效率的方法是呼叫shutil.copytree()函數,但由於這裡需要計算拷貝的檔案數量,因此就沒有呼叫該函數。

若該路徑是一個文件,則首先判斷該文件在目標資料夾中是否存在。若不存在,則拷貝。

由於寫這個腳本主要是為了同步手機相簿到PC,因此只簡單地判斷一下檔案名稱。若要判斷不同名但相同的文件,則可以繼續判斷md5值,這裡就不再贅述。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
  
# 输入两个文件夹a和b路径,将a中的文件拷进b,并计算拷贝的文件数。重复的不作处理。
# pythontab.com 2013-07-19
import os
import shutil
  
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
  
def test():
    src_dir = os.path.abspath(raw_input('Please enter the source path: '))
    if not os.path.isdir(src_dir):
        print 'Error: source folder does not exist!'
        return 0
      
    dst_dir = os.path.abspath(raw_input('Please enter the destination path: '))
    if os.path.isdir(dst_dir):
        num = copyFiles(src_dir, dst_dir)
    else:
        print 'Destination folder does not exist, a new one will be created.'
        os.makedirs(dst_dir)
        num = copyFiles(src_dir, dst_dir)
  
    print 'Copy complete:', num, 'files copied.'
  
if __name__ == '__main__':
    test()


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn