Python写的增量备份文件脚本
来源:互联网 发布:linux ftp 20端口 编辑:程序博客网 时间:2024/05/19 02:00
自己有很多资料需要备份到别的地方。问题是之前也做过备份,但是随着资料的不断更新和增加,就会出现原来做的备份跟现在要备份的资料既有重复的,又有新的,或者是虽然文件名相同,但是内容已经更新了的文件。如果再次备份的话,就需要重新把最新的资料拷贝一遍到目标存储中。如果资料不是很多还好,一旦资料很多且体积庞大,如此没有差别的拷贝就要花费很多冤枉时间进行覆盖目标存储中相同的资料。能不能只备份新的和已更新的资料,而不拷贝相同的资料呢?这就是这个脚本的用处,该脚本能够实现增量备份资料功能。
由于该脚本使用纯Python编写,故需要电脑上具备可用的Python解释器环境才能运行该代码。使用方法:把代码拷贝到一个空文件中,然后把文件保存成“xxx.py”格式,然后运行命令:python xxx.py即可运行。
顺便提示:Python版本最好使用2.5.4版本,该版本不但稳定,而且相对比较高效。该脚本可能不支持3.0及以上的Python版本。关于Python的安装及环境设置方法,网络上有很多,就不再这里啰嗦了。
该脚本有两个版本:一个适用于Linux系统;一个适用于Windows系统。同时,本人还提供一个EXE文件,供那些不想在电脑上安装Python解释器的朋友使用,如果需要下载,请在CSDN下载频道里搜索用户名为dbsync上传的资源。
由于Linux系统对中文支持不是很好,如果在Linux系统上打开该代码,其中的注释可能会显示为乱码。
该脚本经过本人实际应用,都能正常使用。需要注意的一点是所要备份的文件名不能过长,否则可能会备份失败。
本次脚本提供日志功能,所有的备份日志都会被记录并保存在一个文件中。
如果有什么问题,欢迎给我留言,大家共同学习讨论。
以下是源代码:
===================华丽分割线:-)========================
Linux系统所用:
#coding=utf8
#! /usr/bin/env python
import os
mark=0 #全局变量,统计总共有多少文件被复制
def logs(value): #记录日志函数
v1=open('backup_files.log','ab')
v1.write(value)
v1.close()
def erro(value1,value2,value3): #搜集错误信息函数
renameerro={} #存放重命名失败的文件名及失败原因
copyerro={} #存放复制失败的文件名及失败原因
removerro={} #存放删除失败的文件名及失败原因
mkdirerro={} #存放创建路径失败的路径名及失败原因
if value1=='renameerro' and value2 not in renameerro.keys():
renameerro[value2]=value3
elif value1=='copyerro' and values2 not in copyerro.keys():
copyerro[value2]=value3
elif value1=='removerro' and value2 not in removerro.keys():
removerro[value2]=value3
elif value1=='mkdirerro' and value2 not in mkdirerro.keys():
mkdirerro[value2]=value3
else:
pass
v1=[renameerro,copyerro,removerro,mkdirerro]
return v1
def printerro(value): #打印错误信息函数
renameerro=value[0]
copyerro=value[1]
removerro=value[2]
mkdirerro=value[3]
if len(renameerro)!=0:
print '/n---These are the files to rename faise:'
tmp='/n---These are the files to rename faise:'
logs(tmp)
for a in renameerro.keys():
print a+',The reason is:'+str(renameerro[a])
tmp=a+',The reason is:'+str(renameerro[a])
logs(tmp)
if len(copyerro)!=0:
print '/n---These are the files to copy faise:'
tmp='/n---These are the files to copy faise:'
logs(tmp)
for a in copyerro.keys():
print a+',The reason is:'+str(copyerro[a])
tmp=a+',The reason is:'+str(copyerro[a])
logs(tmp)
if len(removerro)!=0:
print '/n---These are the files to remove faise:'
tmp='/n---These are the files to remove faise:'
logs(tmp)
for a in removerro.keys():
print a+',The reason is:'+str(removerro[a])
tmp=a+',The reason is:'+str(removerro[a])
logs(tmp)
if len(mkdirerro)!=0:
print '/n---These are the files to create path faise:'
tmp='/n---These are the files to create path faise:'
logs(tmp)
for a in mkdirerro.keys():
print a+',The reason is:'+str(mkdirerro[a])
tmp=a+',The reason is:'+str(mkdirerro[a])
logs(tmp)
def src_dir(): #源端路径设置函数
while 1:
v1=raw_input('/n---Please enter the source path:/n/n>>')
if len(v1)==0:
print '/n---Error!! Source path can not be NULL!'
continue
if not os.path.exists(v1): #判断该路径是否存在
print '/n---Error!! Source path is not exist!'
continue
v2=os.walk(v1)
mark=0 #判断该路径下是否有文件
for a in v2:
if a[2]!=0:
mark=1
break
if mark==0:
print '/n---Error!! Without any valid files in source path!'
exit() #没有文件的话,整个脚本退出
else:
break
return v1
def targ_dir(): #目标端路径设置函数
while 1:
mark=0
v1=raw_input('/n---Please enter the target path:/n/n>>')
if len(v1)==0:
print '/n---Error!! The target path can not be NULL!'
mark=1
continue
if not os.path.exists(v1): #判断该路径是否存在
print '/n---Error!!Target-side path does not exist'
mark=1
continue
if mark==0:
break
return v1
def copyfile(src,targ): #文件拷贝函数
v1=open(src,'rb') #打开源端文件
v2=open(targ,'wb') #打开目标端文件
print '/n---Copying file %s ....'%src
while True: #拷贝循环
v3=v1.read(1024*15000) #每次从源端文件中读取15MB的内容
v2.write(v3) #把数据写入目标端文件
if len(v3)<1024*15000: #判断源端文件是否被全部读完
break
v1.close()
v2.close()
print '/n---Complete copy of the file %s '%src
tmp='/n---Complete copy of the file %s '%src
logs(tmp)
def main(src,targ): #主函数
global mark #使用全局变量mark,统计总共有多少文件被复制
v1=os.listdir(src) #获得源端目录下所有的文件及文件夹
for a in v1: #备份文件主循环
if os.path.isfile(src+'/'+a): #判断是否为文件
if os.path.exists(targ+'/'+a): #如果该文件在目标端已经存在
if os.path.getsize(src+'/'+a)>os.path.getsize(targ+'/'+a): #如果源端文件的大小大于目标端
while True: #确定重命名后的文件名称
if os.path.exists(targ+'/'+a+'.bak'):
a=a+'.bak'
continue
else:
break
try:
os.rename(targ+'/'+a,targ+'/'+a+'.bak') #重命名目标端该文件
except Exception,e:
print '/n---Error!! Rename the file error : %s'%(targ+'/'+a)
erro('renameerro',targ+'/'+a,e)
print e
continue #如果重命名失败,则不再处理该文件,进入主循环的下一次循环
try:
copyfile(src+'/'+a,targ+'/'+a) #开始复制文件
except Exception,e:
print '/n---Error!! Copy the file error : %s'%(src+'/'+a)
erro('copyerro',src+'/'+a,e)
print e
continue #如果复制失败,则不再处理该文件,进入主循环的下一次循环
try:
os.remove(targ+'/'+a+'.bak') #移除目标端旧的文件
mark=mark+1
except Exception,e:
print '/n---Error!! Remove the file error : %s'%(targ+'/'+a+'.bak')
erro('removerro',targ+'/'+a+'.bak',e)
print e
continue #如果删除失败,则不再处理该文件,进入主循环的下一次循环
elif os.path.getmtime(src+'/'+a)>os.path.getmtime(targ+'/'+a): #如果源端文件的最新修改日期比目标端文件新
while True:
if os.path.exists(targ+'/'+a+'.bak'):
a=a+'.bak'
continue
else:
break
try:
os.rename(targ+'/'+a,targ+'/'+a+'.bak')
except Exception,e:
print '/n---Error!! Rename the file error : %s'%(targ+'/'+a)
erro('renameerro',targ+'/'+a,e)
print e
continue
try:
copyfile(src+'/'+a,targ+'/'+a)
except Exception,e:
print '/n---Error!! Copy the file error : %s'%(src+'/'+a)
erro('copyerro',src+'/'+a,e)
print e
continue
try:
os.remove(targ+'/'+a+'.bak')
mark=mark+1
except Exception,e:
print '/n---Error!! Remove the file error : %s'%(targ+'/'+a+'.bak')
erro('removerro',targ+'/'+a+'.bak',e)
print e
continue
else:
pass
else: #如果该文件在目标端不存在
if not os.path.isdir(targ): #如果该文件所在路径在目标端不存在
try:
os.makedirs(targ) #在目标端建立相应的路径
except Exception,e:
print '/n---Error!! Error creating path : %s'%(targ)
erro('mkdirerro',targ,e)
print e
continue
try:
copyfile(src+'/'+a,targ+'/'+a)
mark=mark+1
except Exception,e:
print '/n---Error!! Copy file error : %s'%(src+'/'+a)
erro('copyerro',src+'/'+a,e)
print e
continue
else: #如果a是个文件夹
main(src+'/'+a,targ+'/'+a) #再次调用主函数
return mark
if __name__=='__main__':
v1=src_dir()
v2=targ_dir()
v3=main(v1,v2)
print '/n--- All files processed! Handled a total of %d files !'%v3
tmp='/n--- All files processed! Handled a total of %d files !'%v3
logs(tmp)
printerro(erro('1','2','3'))
print '/n---Run log saved in the file "backup_files.log"'
===================华丽分割线:-)========================
Windows系统所用:
#coding=gb18030
#! //usr//bin//env python
import os
import time
mark=0 #全局变量,统计总共有多少文件被复制
def logs(value): #记录日志函数
v1=open('backup_files.log','ab')
v1.write(value)
v1.close()
def processunicode(value): #处理unicode类型字符串
v1=''
for a in value:
if type(a)==unicode:
v1=v1+str(a).encode('gb18030')
else:
v1=v1+str(a)
return v1
def src_dir(): #源端路径设置函数
while 1:
v1=raw_input('/n---请输入源端绝对路径:/n/n>>')
if len(v1)==0:
print '/n---错误!!源端路径不能为空!'
continue
if not os.path.exists(v1): #判断该路径是否存在
print '/n---错误!!该路径不存在!'
continue
v2=os.walk(v1)
mark=0 #判断该路径下是否有文件
for a in v2:
if a[2]!=0:
mark=1
break
if mark==0:
print '/n---警告:该路径下没有任何有效文件,脚本退出!'
exit() #没有文件的话,整个脚本退出
else:
break
return v1
def erro(value1,value2,value3): #搜集错误信息函数
renameerro={} #存放重命名失败的文件名及失败原因
copyerro={} #存放复制失败的文件名及失败原因
removerro={} #存放删除失败的文件名及失败原因
mkdirerro={} #存放创建路径失败的路径名及失败原因
if value1=='renameerro' and value2 not in renameerro.keys():
renameerro[value2]=value3
elif value1=='copyerro' and values2 not in copyerro.keys():
copyerro[value2]=value3
elif value1=='removerro' and value2 not in removerro.keys():
removerro[value2]=value3
elif value1=='mkdirerro' and value2 not in mkdirerro.keys():
mkdirerro[value2]=value3
else:
pass
v1=[renameerro,copyerro,removerro,mkdirerro]
return v1
def printerro(value): #打印错误信息函数
renameerro=value[0]
copyerro=value[1]
removerro=value[2]
mkdirerro=value[3]
if len(renameerro)!=0:
print '/n---重命名失败的文件及原因如下:'
tmp='/n---重命名失败的文件及原因如下:'
logs(tmp)
for a in renameerro.keys():
print a+',原因是:'+renameerro[a]
tmp=a+',原因是:'+renameerro[a]
logs(tmp)
if len(copyerro)!=0:
print '/n---复制失败的文件及原因如下:'
tmp='/n---复制失败的文件及原因如下:'
logs(tmp)
for a in copyerro.keys():
print a+',原因是:'+copyerro[a]
tmp=a+',原因是:'+copyerro[a]
logs(tmp)
if len(removerro)!=0:
print '/n---删除失败的文件及原因如下:'
tmp='/n---删除失败的文件及原因如下:'
logs(tmp)
for a in removerro.keys():
print a+',原因是:'+removerro[a]
tmp=a+',原因是:'+removerro[a]
logs(tmp)
if len(mkdirerro)!=0:
print '/n---创建失败的路径名及原因如下:'
tmp='/n---创建失败的路径名及原因如下:'
logs(tmp)
for a in mkdirerro.keys():
print a+',原因是:'+mkdirerro[a]
tmp=a+',原因是:'+mkdirerro[a]
logs(tmp)
def targ_dir(): #目标端路径设置函数
while 1:
mark=0
v1=raw_input('/n---请输入目标端绝对路径:/n/n>>')
if len(v1)==0:
print '/n---错误!!目标端路径不能为空!'
mark=1
continue
if not os.path.exists(v1): #判断该路径是否存在
print '/n---错误!!该路径不存在!'
mark=1
continue
if mark==0:
break
return v1
def copyfile(src,targ): #文件拷贝函数
v1=open(src,'rb') #打开源端文件
v2=open(targ,'wb') #打开目标端文件
print '/n---正在备份文件: %s ....'%src
while True: #拷贝循环
v3=v1.read(1024*15000) #每次从源端文件中读取15MB的内容
v2.write(v3) #把数据写入目标端文件
if len(v3)<1024*15000: #判断源端文件是否被全部读完
break
v1.close()
v2.close()
print '/n---文件 %s 备份完毕!'%src
writefiles='/n---文件 %s 备份完毕!'%src
logs(writefiles)
def main(src,targ): #主函数
global mark #使用全局变量mark,统计总共有多少文件被复制
v1=os.listdir(src) #获得源端目录下所有的文件及文件夹
for a in v1: #备份文件主循环
if os.path.isfile(src+'//'+a): #判断是否为文件
if os.path.exists(targ+'//'+a): #如果该文件在目标端已经存在
if os.path.getsize(src+'//'+a)>os.path.getsize(targ+'//'+a): #如果源端文件的大小大于目标端
while True: #确定重命名后的文件名称
if os.path.exists(targ+'//'+a+'.bak'):
a=a+'.bak'
continue
else:
break
try:
os.rename(targ+'//'+a,targ+'//'+a+'.bak') #重命名目标端该文件
except Exception,e:
print '/n---错误!!重命名文件 %s 时发生错误:'%(targ+'//'+a)
erro('renameerro',targ+'//'+a,processunicode(e))
print processunicode(e)
continue #如果重命名失败,则不再处理该文件,进入主循环的下一次循环
try:
copyfile(src+'//'+a,targ+'//'+a) #开始复制文件
except Exception,e:
print '/n---错误!!在备份文件 %s 时发生错误:'%(src+'//'+a)
erro('copyerro',src+'//'+a,processunicode(e))
print processunicode(e)
continue #如果复制失败,则不再处理该文件,进入主循环的下一次循环
try:
os.remove(targ+'//'+a+'.bak') #移除目标端旧的文件
mark=mark+1
except Exception,e:
print '/n---错误!!在删除目标端文件 %s 时发生错误:'%(targ+'//'+a+'.bak')
erro('removerro',targ+'//'+a+'.bak',processunicode(e))
print processunicode(e)
continue #如果删除失败,则不再处理该文件,进入主循环的下一次循环
elif os.path.getmtime(src+'//'+a)>os.path.getmtime(targ+'//'+a): #如果源端文件的最新修改日期比目标端文件新
while True:
if os.path.exists(targ+'//'+a+'.bak'):
a=a+'.bak'
continue
else:
break
try:
os.rename(targ+'//'+a,targ+'//'+a+'.bak')
except Exception,e:
print '/n---错误!!在重命名目标端文件 %s 时发生错误:'%(targ+'//'+a)
erro('rename',targ+'//'+a,processunicode(e))
print processunicode(e)
continue
try:
copyfile(src+'//'+a,targ+'//'+a)
except Exception,e:
print '/n---错误!!在备份文件 %s 时发生错误:'%(src+'//'+a)
erro('copyerro',src+'//'+a,processunicode(e))
print processunicode(e)
continue
try:
os.remove(targ+'//'+a+'.bak')
mark=mark+1
except Exception,e:
print '/n---错误!!在删除目标端文件 %s 时发生错误:'%(targ+'//'+a+'.bak')
erro('removerro',targ+'//'+a+'.bak',processunicode(e))
print processunicode(e)
continue
else:
pass
else: #如果该文件在目标端不存在
if not os.path.isdir(targ): #如果该文件所在路径在目标端不存在
try:
os.makedirs(targ) #在目标端建立相应的路径
except Exception,e:
print '/n---错误!!在创建目标端路径 %s 时发生错误:'%(targ)
erro('mkdirerro',targ,processunicode(e))
print processunicode(e)
continue
try:
copyfile(src+'//'+a,targ+'//'+a)
mark=mark+1
except Exception,e:
print '/n---错误!!在备份文件 %s 时发生错误:'%(src+'//'+a)
erro('copyerro',src+'//'+a,processunicode(e))
print processunicode(e)
continue
else: #如果a是个文件夹
main(src+'//'+a,targ+'//'+a) #再次调用主函数
return mark
if __name__=='__main__':
v1=src_dir()
v2=targ_dir()
v3=main(v1,v2)
print '/n---所有文件备份完毕!共有 %d 个文件被备份!'%v3
printerro(erro('1','2','3'))
tmp='/n---所有文件备份完毕!共有 %d 个文件被备份!'%v3
logs(tmp)
print '/n---运行日志保存在文件“backup_files.log”中。'
v4=raw_input('/n---按 回车键 退出脚本....')
- Python写的增量备份文件脚本
- 备份文件的python脚本
- 实验室的一段Python脚本 “备份文件操作”
- python 备份文件脚本
- Python备份文件脚本
- 用Python写脚本,完全备份和增量备份
- 备份文件的脚本
- 简单的备份文件脚本
- 用python脚本定期备份文件
- 编写Python脚本来备份文件
- 第一个自己写的python程序:windows下备份文件
- 定时备份文件的BAT脚本
- 用python编写脚本实现备份文件
- 初学python —— 备份文件脚本
- 增量备份文件工具
- 使用ROBOCOPY增量备份文件
- python写的打包脚本
- python写的投票脚本
- 关于CMNET和CMWAP联网实践
- 关于想把对话框派生类直接通过MFC的规则动态库导出的思考
- 3DES算法
- 项目团队的成功之道
- 唠叨着继续
- Python写的增量备份文件脚本
- poj2406——Power Strings
- SMF(service management facility)功能的描述
- Qt系列软件包 (Qtopia Core,Qt Extended,Qt-embedded的区别)
- 唠叨着继续
- 网站静态化方案
- mp3播放问题
- 追女必读
- 给未来一个机会