重要文件备份脚本

一个用于实现文件筛选并备份的Python脚本。有如下功能:

  • 全局单文件大小限制(筛出了过大的音视频等文件)
  • 个别扩展名的扩大文件大小限制(避免筛选出稍大的图片、压缩包等)
  • 时间限制,增量备份
  • 仅更新大小不同的文件
  • 支持多语言文件名
  • 可跨平台
  • 有直观的文本输出
  • 脚本可扩展,可稍加修改实现可选的全局总大小限制、扩展名限制等

注意使用时要保存为UTF-8编码,以免出编码问题。

from sys import stdout
import os
import shutil
import time

#highprext = [".doc",".docx",".rtf",".xls","xlsx",".ppt",".pps",".pptx"] #可选的限制文件类型
otherext = [".pdf",".gif",".jpg",".png",".tif",".bmp",".zip",".tar",".tgz",".gz","7z",".rar",".z",".mov",".mpg",".mpeg",".avi",".asf",".mp3",".mp2",".rm",".wav",".vob",".qt",".vid",".ac3",".wma",".wmv"] #个别扩展名的扩大文件大小限制
maxsizeone = 2*1024*1024  #全局单文件大小限制,Bytes
maxsizetwo = 16*1024*1024 #扩大单文件大小限制,Bytes
copyafter = time.mktime(time.strptime('2013-11-16 12:00:00', '%Y-%m-%d %X'))
#增量备份的时间限制

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
def humansize(nbytes):
    '''可读的文件大小'''
    if nbytes == 0: return '0 B'
    i = 0
    while nbytes >= 1024 and i < len(suffixes)-1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])

# main
rootdir = u"从哪个文件夹拷贝,斜杠\要双写".rstrip("\\")
todir = u"拷到哪个文件夹,斜杠\要双写".rstrip("\\")
print "Copying..."
fcount,filec=0,0
sizesum = 0
starttime = time.clock()
for root, subFolders, files in os.walk(rootdir):
    for name in subFolders:
        tpath = os.path.join(todir,root[len(rootdir):],name)
        if not os.path.exists(tpath):
            try:
                os.makedirs(tpath)
                fcount+=1
            except KeyboardInterrupt:
                break
            except:
                pass
    for name in files:
        try:
            fpath = os.path.join(root,name)
            tpath = os.path.join(todir,root[3:len(root)],name)
            ext = os.path.splitext(fpath)
            size = os.path.getsize(fpath)
            if ((ext[1] not in otherext and size < maxsizeone) or
             (ext[1] in otherext and size < maxsizetwo)) and
             os.path.getmtime(fpath) > copyafter: #判断语句
                if os.path.exists(tpath):
                    if size!=os.path.getsize(tpath):
                        #仅复制文件大小不同的文件
                        shutil.copy2(fpath, tpath)
                        filec+=1
                        sizesum+=size #总大小计数
                else:
                    shutil.copy2(fpath, tpath)
                    filec+=1
                    sizesum+=size
        except KeyboardInterrupt:
            break
        except:
            continue
    stdout.write("\rCopied %s files, %s folders. Total %s. %s..." % (filec,fcount,humansize(sizesum),root[len(rootdir)-1:len(rootdir)+20]))
print rootdir, "Done."
stdout.write("Copied %s files, %s folders. Total %s." % (filec,fcount,humansize(sizesum)))
print "Total time: %.2f s." % time.clock()-starttime