1. 程式人生 > >pyrhon-檔案備份程式(90)

pyrhon-檔案備份程式(90)

import time
import os
import tarfile
import hashlib
import pickle

def check_md5(fname):
    m = hashlib.md5()   #建立md5物件
    with open(fname,'rb') as fobj:
        while True:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)  #更新md5物件
    return m.hexdigest()    #返回md5物件

def full_backup(src_dir,dst_dir,md5file):   #完全備份
    fname = os.path.basename(src_dir.rstrip('/'))   #去除目錄最後的根號(rstrip()),取最後的一個單個檔案(basename())
    fname = '%s_full_%s.tar.gz' % (fname,time.strftime('%Y%m%d'))   #備份後包的名字:檔名_full_日期.tar.gz
    fname = os.path.join(dst_dir,fname) #合併路徑,形成絕對路徑
    md5dict = {}    #定義一個字典,用於放檔名和對應的md5值

    tar = tarfile.open(fname,'w:gz')    ###對檔案進行打包
    tar.add(src_dir)    #新增要打包的目錄
    tar.close()

    for path,folders,files in os.walk(src_dir): #walk(),遍歷目錄樹,自頂向下或自底向上生成目錄樹下的檔名
        for each_file in files:
            key = os.path.join(path,each_file)  #合併路徑
            md5dict[key] = check_md5(key)   #新增到字典

        with open(md5file,'wb') as fobj:
            pickle.dump(md5dict,fobj)   #將字典的內容新增到檔案中

def incr_backup(src_dir,dst_dir,md5file):   #增量備份
    fname = os.path.basename(src_dir.rstrip('/'))
    fname = '%s_incr_%s.tar.gz' % (fname,time.strftime('%Y%m%d'))
    fname = os.path.join(dst_dir,fname)
    md5dict = {}

    with open(md5file,'rb') as fobj:
        oldmd5 = pickle.load(fobj)      #將舊的md5值從檔案內取出來

    for path,folders,files in os.walk(src_dir):
        for each_file in files:
            key = os.path.join(path,each_file)
            md5dict[key] = check_md5(key)   #向字典內新增新的md5值

    with open(md5file,'wb') as fobj:
        pickle.dump(md5dict,fobj)   #將新的那個md5字典內容寫入檔案內

    tar = tarfile.open(fname,'w:gz')
    for key in md5dict:     #迴圈遍歷,將舊的字典內容與新的字典內容進行比對,然後將有改變的檔案進行打包
        if oldmd5.get(key) != md5dict[key]:
            tar.add(key)
    tar.close()

if __name__ == '__main__':
    #mkdir /tmp/backup;cp -r /etc/security /tmp/
    src_dir = '/tmp/security'
    dst_dir = '/tmp/backup'
    md5file = '/tmp/backup/md5.data'
    if time.strftime('%a') == 'Mon':    #星期一,完全備份,否則增量備份
        full_backup(src_dir,dst_dir,md5file)
    else:
        incr_backup(src_dir,dst_dir,md5file)