python開發目錄合並小工具 PathMerge


前言

這個程序陸陸續續開發了幾天,正好我在學Python,就一邊做一邊學,倒是學到不少東西。

不得不說python是快速開發的好工具。

程序做了一些改進,這兩天又忙着畢設,現在才想起來發到博客上。想想回頭github也要啟用起來,不能繼續荒廢了……

如果嫌運行python程序不方便的話,可以直接使用exe可執行文件版本。

exe發布器在這里:使用pyInstaller發布PathMerge的exe版本(py轉換成exe)

廢話不多說,我介紹一下這個工具。

應用場景

在日常使用中,我們往往需要把一個文件夾拷到另一個文件夾下面,做一些修改之后,再將改動的文件夾合並回去。

例如,從優盤中把一個要用的文件夾拷到電腦上,在pc機上工作,之后你需要將修改后的文件夾再拷回優盤中帶走。

這個時候問題來了。

如果你做的修改不多,我們可以簡單的把修改的文件復制回去,這個時候你清楚的記得你到底修改了哪些文件。

但是如果你對很多文件做了改動,並且還創建了幾個文件或者文件夾,導致目錄結構變得十分復雜,最后你自己都記不起來到底哪些文件做了哪些改動,目錄做了哪些更新,這個時候你要把文件夾合並回去就有些凌亂了……

So,你需要一個工具去幫你記憶你做的改動,自動的幫你合並文件夾,並且不會丟失任何文件。

這個時候這個小工具就可以派上用場了~

下面演示一下怎么用。

使用演示

現在有兩個工作空間

工作空間1是你之前做好的一個工程或者文件夾,里面放滿了文件,目錄結構復雜。

詳細目錄:

工作空間2是你現在要工作的目錄,現在是空的。

我們把要用的文件夾拷過來

並在里面做一些改動。

這里不放圖了,總之我創建了一個文件夾,創建了兩個文件,修改了三個文件……現在目錄結構變成這樣:

大家看到,1/下多了一個文件夾33,里面多了兩個文件111.txt和222.txt,我還修改了一個txt文件,一個ppt文件和一個word文件。

下面運行PathMerge:

輸入A目錄(修改的文件夾)和B目錄(原文件夾),要將A==>B,A合並到B。

回車開始合並:

合並成功!

合並的記錄都列在上面了,如果名稱相同的文件會將舊文件創建一個副本,修改后的文件直接復制過去,程序中沒有刪除文件的代碼,可放心食用。

上圖可知復制了三個文件,創建了三個舊文件副本,另外復制了創建的目錄。

將工作空間2中1文件做的所有改動都包含了進去。

以上,就是PathMerge的使用演示。

代碼

 1 # coding=gbk
 2 
 3 # PathMerge.py
 4 # 作者:freecode
 5 # 創建時間:2016.4.9 20:15
 6 # 作用:
 7 # 合並並兩個目錄/文件夾。
 8 # 將目錄A合並到目錄B,同級目錄下,
 9 # 將A中有,B中沒有的目錄完全復制到B中;
 10 # 將A中沒有,B中有的目錄不做改動;
 11 # 將A中做了修改的文件,在B的同級目錄下創建一個副本。(注意不是覆蓋)
 12 #  13 # 適應場景:
 14 # 一般A是從B復制過來的文件夾,做了修改后,想合並回B。
 15 # 這樣在A中做的一些改動我們就不知道了,這個程序的作用是,
 16 # 將A中修改的部分在B中更新。
 17 #  18 # 版本:
 19 # 將修改后的文件完全復制過去
 20 # 舊的文件創建副本
 21 # 基於文件的MD5值判斷是否修改過
 22 #  23 
 24 import os  25 import shutil  26 import time  27 import hashlib  28 import sys  29 
 30 def Help():     # 輸出幫助文檔
 31   print """  
 32 PathMerge.py  33 作者:freecode  34 創建時間:2016.4.9 20:15  35 作用:  36  合並並兩個目錄/文件夾。  37  將目錄A合並到目錄B,同級目錄下,  38  將A中有,B中沒有的目錄完全復制到B中;  39  將A中沒有,B中有的目錄不做改動;  40  將A中做了修改的文件,在B的同級目錄下創建一個副本。(注意不是覆蓋)  41 
 42 適應場景:  43  一般A是從B復制過來的文件夾,做了修改后,想合並回B。  44  這樣在A中做的一些改動我們就不知道了,這個程序的作用是,  45  將A中修改的部分在B中更新。  46 
 47 版本:  48  將修改后的文件完全復制過去  49  舊的文件創建副本  50  基於文件的MD5值判斷是否修改過  51 """
 52 
 53 def GetFileMd5(filename):       # 計算文件的md5值
 54     if not os.path.isfile(filename):  55         return
 56     myhash = hashlib.md5()  57     f = file(filename,'rb')  58     while True:  59         b = f.read(8096)  60         if not b :  61             break
 62  myhash.update(b)  63  f.close()  64     return myhash.hexdigest()  65 
 66 def isModify(A_file,B_file):        # 判斷兩個文件是否相同,如果不同,表示修改過
 67     # 參數需是絕對路徑
 68     return  GetFileMd5(A_file) != GetFileMd5(B_file)  69 
 70 def Stamp2Time(Stamp):      # 將時間戳轉換成時間顯示格式
 71     timeArray = time.localtime(Stamp)  72     Time = time.strftime("%Y年%m月%d日 %H時%M分%S秒 舊文件副本", timeArray)  73     return Time  74 
 75 def Merge(A_path,B_path):       # 合並兩個目錄
 76     B_paths = os.listdir(B_path)    # 獲取當前B中的目錄結構
 77     for fp in os.listdir(A_path):   # 遍歷當前A目錄中的文件或文件夾
 78         A_new_path = os.path.join(A_path,fp)    # A中的文件或目錄
 79         B_new_path = os.path.join(B_path,fp)    # B中對應的文件或路徑,不一定存在
 80 
 81         if os.path.isdir(A_new_path):           # A中的目錄
 82             if os.path.exists(B_new_path):      # 如果在B中存在
 83                 Merge(A_new_path,B_new_path)    # 繼續合並下一級目錄
 84             else:   # 如果在B中不存在
 85                 print '[目錄]\t%s ===> %s' %(A_new_path,B_new_path)  86                 shutil.copytree(A_new_path,B_new_path)   # 完全復制目錄到B
 87                 
 88         elif os.path.isfile(A_new_path):        # A中的文件
 89             if os.path.exists(B_new_path):      # 如果在B中存在
 90                 s = os.stat(B_new_path)  91                 if isModify(A_new_path,B_new_path) == True:  # 如果該文件修改過
 92                     # 創建副本
 93                     suffix = B_new_path.split('.')[-1]  # 得到文件的后綴名
 94                     # 將B中原文件創建副本
 95                     B_copy_path = B_new_path[:-len(suffix)-1]+"(%s)."%(Stamp2Time(s.st_mtime))+suffix  96                     print '[副本]\t%s ===> %s' %(A_new_path,B_copy_path)  97  shutil.copy2(B_new_path,B_copy_path)  98                     # 將A中修改后文件復制過來
 99                     print '[文件]\t%s ===> %s' %(A_new_path,B_new_path) 100  shutil.copy2(A_new_path,B_new_path) 101                 else:  # 如果該文件沒有修改過
102                     pass    # 不復制
103                 
104             else:   # 如果在B中不存在
105                 # 將該文件復制過去
106                 print '[文件]\t%s ===> %s' %(A_new_path,B_new_path) 107  shutil.copy2(A_new_path,B_new_path) 108 
109 # 運行模式
110 if __name__=='__main__': 111     print """
112  歡迎使用PathMerge! 113  本程序將會把目錄A合並到目錄B,即 A ===> B 114  將A目錄中修改的內容在B目錄中更新 115  合並規則具體見 PathMerge.Help() 116         """
117     if len(sys.argv) == 1: 118         path1 = raw_input('請輸入A目錄:').strip() 119         path2 = raw_input('請輸入B目錄:').strip() 120     elif len(sys.argv) == 2: 121         path1 = sys.argv[1].strip() 122         print 'A目錄為:%s\n' % (path1) 123         path2 = raw_input('請輸入B目錄:').strip() 124     elif len(sys.argv) == 3: 125         path1 = sys.argv[1].strip() 126         print 'A目錄為:%s\n' % (path1) 127         path2 = sys.argv[2].strip() 128         print 'B目錄為:%s\n' % (path2) 129     else: 130         print 'ERROR:參數錯誤!\n參數最多有三個!\n'
131         raw_input('\n請按回車鍵(Enter)退出……') 132  sys.exit(0) 133     # 去除目錄的引號
134     if path1[0]=='\"': 135       path1 = path1[1:-1] 136     if path2[0]=='\"': 137       path2 = path2[1:-1] 138 
139     print """
140 開始合並目錄 %s 141    到目錄 %s 142 %s ===> %s 143 """ %(path1,path2,path1,path2) 144 
145     try: 146         print '合並中……'
147  Merge(path1,path2) 148         print ''
149     except Exception,e: 150         print '合並失敗!'
151         print '失敗原因:\n',e 152     else: 153         print '合並成功!'
154 
155     raw_input('\n請按回車鍵(Enter)退出……') 156     

工具特性

1、可識別加“”的目錄和不加“”的目錄。

2、使用MD5識別文件是否修改。

MD5識別文件的內容見上一篇博文:python計算文件的md5值

3、可傳遞參數,用來寫腳本。例:

4、原文件夾內的舊文件不會被刪除,而是創建一個帶有時間戳的副本。修改過的文件直接復制過去。

  這樣不用擔心合並之后文件莫名其妙的丟失啦。使用該工具不會有文件刪除操作。

注意

Sorry,目前僅支持windows環境……

參考資料

python 文件拷貝、移動

原創聲明

Freecode# : www.cnblogs.com/yym2013

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM