這篇文章主要介紹了Python實現SVN的目錄周期性備份,實例分析了Python實現SVN周期性備份的原理與實現技巧,具有一定參考借鑒價值,需要的朋友可以參考下
本文實例講述了Python實現SVN的目錄周期性備份方法。分享給大家供大家參考。具體如下:
起因:今天用SVN時,不小心把遠程SVN服務器上的目錄刪掉了,然后在本地又手賤地還原了一下項目(eclipse中右鍵項目team => 還原),導致寫了大半天的代碼全部丟失,用多款數據恢復軟件恢復也無果。一怒之下寫了這個目錄周期性備份小工具,每隔5秒備份源目錄中的所有文件到目標目錄(保留結構),保證目標目錄中的文件只增不減。且每次只拷貝發生變化的文件(比較兩個文件的MD5值)。
思考:雖然SVN也是一個版本管理軟件,但在使用過程總覺得它的諸多操作挺別扭,相比而言Git更強大靈活。我自己理想中的版本控制軟件至少應該考慮到一些讓用戶產生較強挫敗的使用場景(也許大部分情況是因為用戶誤用,但如果誤用情況也能考慮到,才能更體現軟件的終極人文關懷嘛),比如刪除遠程服務器上的文件,我覺得應該設計成這樣:即使用戶刪除了文件,文件還應該在一個緩沖區中呆1天(或幾個小時,可以配置),然后由一個定時任務定時刪除緩沖區中停留時間超過1天的文件。而不是立即物理刪除。
TODO:
增加配置文件,做成命令行程序
md5_caculate.py:
- # -*- coding: utf-8 -*-
- #!/usr/bin/python
- from hashlib import md5
- import os
- def calMD5(str):
- m = md5()
- m.update(str)
- return m.hexdigest()
- def calMD5ForFile(file):
- statinfo = os.stat(file)
- if int(statinfo.st_size) / (1024*1024) >= 1000:
- # print("File size > 1000, move to big file...")
- return calMD5ForBigFile(file)
- m = md5()
- f = open(file, 'rb')
- m.update(f.read())
- f.close()
- return m.hexdigest()
- def calMD5ForFolder(dir, MD5File):
- outfile = open(MD5File,'w')
- for root, subdirs, files in os.walk(dir):
- for file in files:
- filefullpath = os.path.join(root, file)
- """print filefullpath"""
- filerelpath = os.path.relpath(filefullpath, dir)
- md5 = calMD5ForFile(filefullpath)
- outfile.write(filerelpath+' '+md5+"/n")
- outfile.close()
- def calMD5ForBigFile(file):
- m = md5()
- f = open(file, 'rb')
- buffer = 8192 # why is 8192 | 8192 is fast than 2048
- while 1:
- chunk = f.read(buffer)
- if not chunk : break
- m.update(chunk)
- f.close()
- return m.hexdigest()
- if __name__=="__main__":
- print(calMD5ForFile("e:/test/target/a/b/rabbit.txt"))
file_util.py:
- # -*- coding: utf-8 -*-
- #!/usr/bin/python
- import os,shutil
- from md5_caculate import calMD5ForFile
- # 拷貝源目錄到目標目錄
- def copyDir(srcDir, dstDir):
- if srcDir in dstDir: # 源目錄包含在目標目錄,則直接返回
- return
- if not os.path.isdir(srcDir):
- print(srcDir, "路徑指定的源目錄不存在!")
- return;
- if not os.path.exists(dstDir): # 目標目錄不存在時則創建
- os.makedirs(dstDir)
- for fileOrDirName in os.listdir(srcDir): # 源目錄下的所有文件(包括文件和目錄) TODO BUG:如果srcDir為一個空目錄?
- # fileOrDirPath = srcDir + "/" + fileOrDirName
- fileOrDirPath = os.path.join(srcDir, fileOrDirName)
- if os.path.isfile(fileOrDirPath): # 如果當前是一個子文件,則直接復制文件
- copyFile(fileOrDirPath, dstDir)
- if os.path.isdir(fileOrDirPath): # 如果當前是一個子目錄,則遞歸復制目錄
- copyDir(fileOrDirPath, os.path.join(dstDir, fileOrDirName))
- # 拷貝源文件到目標目錄
- def copyFile(srcFile, dstDir):
- if not os.path.isfile(srcFile):
- print(srcFile, "路徑指定的源文件不存在!")
- return
- fileName = os.path.basename(srcFile)
- dstFile = os.path.join(dstDir, fileName)
- if os.path.isfile(dstFile): # 有同名的目標文件,則檢查MD5值是否相同,如果不同才Copy
- if calMD5ForFile(srcFile) != calMD5ForFile(dstFile):
- try:
- shutil.copy(srcFile, dstDir)
- except PermissionError:
- print("PermissionError occurs: ", srcFile)
- else:
- shutil.copy(srcFile, dstDir)
- if __name__=="__main__":
- copyDir("e:/test/src", "e:/test/target")
backuper.py:
- # -*- coding: utf-8 -*-
- #!/usr/bin/python
- import os, time
- from file_util import copyDir
- # -------------------------------------------------------------
- # 定時備份源目錄到目標目錄
- # version = 1.0
- # author = Will
- # -------------------------------------------------------------
- # 定時備份源目錄到目標目錄,sleepIntervalSeconds為備份時間間隔秒數
- def backupDir(srcDir, dstDir, sleepIntervalSeconds):
- if not os.path.isdir(srcDir):
- print("請指定要備份源目錄并確保目錄存在!")
- return;
- while True:
- print("備份:", srcDir, ",到:", dstDir)
- copyDir(srcDir, dstDir)
- print("開始休眠", sleepIntervalSeconds, "秒...")
- time.sleep(sleepIntervalSeconds)
- if __name__=="__main__":
- backupDir("d:/Documents/workspace/workspace/griddle", "e:/backup/griddle", 20)
希望本文所述對大家的Python程序設計有所幫助。
新聞熱點
疑難解答