1. 程式人生 > >利用python實現兩個資料夾的同步

利用python實現兩個資料夾的同步

其實無論windows還是Linux,簡單地去實現兩個兩個資料夾的同步只需系統自帶的複製命令加引數就可以了。

  • WINDOWS :
xcopy 原始檔夾\* 目標資料夾 /s /e /y
  • Linux :
cp -r 原始檔夾/* 目標資料夾

這裡使用python來實現這些基本功能,並增加一些去重之類的增強功能。


1、複製原始檔夾中檔案至目標資料夾 

要想同步兩個資料夾中的資料,基本思路首先需要遍歷原始檔夾中的資訊,將原始檔夾中的檔案複製到目標資料夾。

遍歷資料夾採用os中的listdir函式就可以了。

 1 import os
2 3 path_s = 'F:\\test\\s' 4 path_t = 'F:\\test\\t' 5 6 for filename in os.listdir(path_s): 7 filename_s = path_s+os.sep+filename 8 print '[*] Source :',filename_s 9 filename_t = path_t+os.sep+filename 10 print '[*] Target :',filename_t 11 with open(filename_s,'rb') as f_s:
12 with open(filename_t,'wb') as f_t: 13 f_t.write(f_s.read())

但是很明顯這裡沒有考慮原始檔夾中還會存在資料夾甚至多重資料夾的情況。

2、原始檔夾中存在多重資料夾

一個簡單的思路就是:在遍歷原始檔夾內的檔案時,先判定當前檔案這是檔案還是資料夾。如果當前檔案是資料夾的話,開始遍歷此資料夾內的檔案,如果裡面還有資料夾,遍歷這個資料夾,依次類推。利用遞迴的方法,程式碼如下:

 1 import os
 2 
 3 
 4 path_s = 'F:\\test\\s'
 5 path_t = '
F:\\test\\t' 6 7 8 def copy_file(paths,patht): 9 for filename in os.listdir(paths): 10 filename_s = paths+os.sep+filename 11 filename_t = patht+os.sep+filename 12 if os.path.isdir(filename_s): 13 if not os.path.exists(filename_t): 14 os.mkdir(filename_t) #在目標資料夾中建立對應的資料夾 15 copy_file(filename_s,filename_t) # 遞迴 16 else: 17 print '[*] Source :',filename_s 18 19 print '[*] Target :',filename_t 20 with open(filename_s,'rb') as f_s: 21 with open(filename_t,'wb') as f_t: 22 f_t.write(f_s.read()) 23 24 25 copy_file(path_s,path_t)

目前,簡單的資料夾複製功能已經實現了。

3、目標資料夾中已有檔案不再複製

一個簡單的方法就是在目標資料夾中複製檔案之前先利用函式“os.path.exists”判定這個檔案是否存在。

 1 import os
 2 
 3 
 4 path_s = 'F:\\test\\s'
 5 path_t = 'F:\\test\\t'
 6 
 7 def copy_file(paths,patht):
 8     for filename in os.listdir(paths):
 9         filename_s = paths+os.sep+filename
10         filename_t = patht+os.sep+filename
11         if os.path.isdir(filename_s):
12             if not os.path.exists(filename_t):
13                 os.mkdir(filename_t)
14             copy_file(filename_s,filename_t)
15         else:
16             if os.path.exists(filename_t):
17                 print '[*] "%s" already exists! ' % filename_t
18             else:
19                 print '[*]  Source :',filename_s
20         
21                 print '[*]  Target :',filename_t
22                 with open(filename_s,'rb') as f_s:
23                     with open(filename_t,'wb') as f_t:
24                         f_t.write(f_s.read())
25 
26 copy_file(path_s,path_t)

這個辦法避免了一部分已有檔案的重複複製操作,減少了部分不必要的讀寫操作,但是卻無法消除內容相同但名稱、路徑不同的重複檔案。

4、利用MD5判定重複檔案

目前判定兩個檔案是否相同,除了按位元組逐個對比這個笨方法外,簡單常用的辦法就是利用MD5和CRC校驗,或是按一定規律挑取檔案的指定位置的資料塊就行對比。

這次利用檔案的MD5值,將目標資料夾中已有檔案的MD5值儲存到列表或字典中,每在原始檔夾中讀取一個檔案就判定該檔案的MD5值是否已經存在於MD5列表,沒有的話再進行復制操作,並將該檔案的MD5值寫入列表。

import os
import hashlib

path_s = 'F:\\test\\s'
path_t = 'F:\\test\\t'
list_file = {}

def create_file_list(path):
    for name in os.listdir(path):
        filename = path+os.sep+name
        if os.path.isdir(filename):
            create_file_list(filename)
        else:
            with open(filename,'rb') as f:
                md5 = hashlib.md5(f.read()).hexdigest()
                if md5 not in list_file:
                    list_file[md5] = 1

def copy_file(paths,patht):
    for filename in os.listdir(paths):
        filename_s = paths+os.sep+filename
        filename_t = patht+os.sep+filename
        if os.path.isdir(filename_s):
            if not os.path.exists(filename_t):
                os.mkdir(filename_t)
            copy_file(filename_s,filename_t)
        else:
            if os.path.exists(filename_t):
                print '[*] "%s" already exists! ' % filename_t
            else:
                with open(filename_s,'rb') as f_s:
                    data = f_s.read()
                    file_md5 = hashlib.md5(data).hexdigest()
                    if file_md5 not in list_file:
                        list_file[file_md5] = 1
                        print '[*]  Source :',filename_s
                        print '[*]  Target :',filename_t
                        with open(filename_t,'wb') as f_t:
                            f_t.write(data)
                    else:
                        print '[*] "%s"\'s MD5 already exists! ' % filename_t

create_file_list(path_t)
copy_file(path_s,path_t)
    

 

 

如下圖,執行後內容相同的幾個檔案,只有第一次讀取到的時候才寫入目標資料夾,其他路徑下的檔案並沒有複製到目標資料夾。