参考资料
# !/usr/bin/python3
# coding: utf-8
import hashlib
import os
import traceback
# 路径格式化
def format(path):
if path is None:
return ""
path = path.lstrip()
path = path.rstrip()
while path.find("/") >= 0:
path = path.replace("/", "\\")
while path.find("\\\\") >= 0:
path = path.replace("\\\\", "\\")
return path
# 获取文件指纹
def md5(path):
if not os.path.isfile(path):
return None
try:
hash = hashlib.md5()
f = open(path, "rb")
while True:
b = f.read(1024)
if not b:
break
hash.update(b)
f.close()
return hash.hexdigest()
except:
return None
# 比较文件内容的异同
def diff(file1, file2):
hash1 = md5(file1)
hash2 = md5(file2)
if hash1 is None:
if hash2 is None:
return False
else:
return True
else:
if hash2 is None:
return True
return False if hash1 == hash2 else True
# 深度比较文件夹异同
def same(folder1, folder2):
list1 = os.listdir(folder1)
list2 = os.listdir(folder2)
if len(list1) != len(list2):
return False
join = list(set(list1).intersection(set(list2)))
if len(list1) != len(join):
return False
dirList = []
for name in list1:
file1 = os.path.join(folder1, name)
file2 = os.path.join(folder2, name)
file1 = format(file1)
file2 = format(file2)
if (os.path.isfile(file1) and os.path.isdir(file2)) \
or (os.path.isdir(file1) and os.path.isfile(file2)):
return False
else:
if os.path.isdir(file1):
dirList.append(name)
else:
if diff(file1, file2):
return False
for name in dirList:
dir1 = os.path.join(folder1, name)
dir2 = os.path.join(folder2, name)
dir1 = format(dir1)
dir2 = format(dir2)
if not same(dir1, dir2):
return False
return True
# 深度罗列文件内所有文件
def deepListDir(folder):
fList = os.listdir(folder)
list = []
for fn in fList:
# fn: file name
# fp: file path
fp = os.path.join(folder, fn)
fp = format(fp)
if os.path.isfile(fp):
list.append(fp)
elif os.path.isdir(fp):
ls = deepListDir(fp)
if len(ls) > 0:
list.extend(ls)
return list
# 深度移除文件夹所有内容
def deepRemove(folder):
assert (os.path.isdir(folder))
files = os.listdir(folder)
for file in files:
path = os.path.join(folder, file)
path = format(path)
if os.path.isdir(path):
deepRemove(path)
continue
try:
os.remove(path)
except:
print("Del file %s failed" % path)
try:
os.rmdir(folder)
except:
print("Del folder %s failed" % path)
# 文件内容覆盖
def fileOverride(src, tgt):
assert (os.path.isfile(src))
f1 = None
f2 = None
try:
f1 = open(src, 'rb')
f2 = open(tgt, 'wb')
f2.write(f1.read())
except:
print("Copy file %s to %s failed" % (src, tgt))
traceback.print_exc()
finally:
if f2 is not None:
f2.close()
if f1 is not None:
f1.close()
# 深度覆盖文件夹内容
def deepOverride(src, tgt):
assert (os.path.isdir(src))
files = os.listdir(src)
if not os.path.exists(tgt):
os.makedirs(tgt)
for file in files:
path1 = os.path.join(src, file)
path2 = os.path.join(tgt, file)
path1 = format(path1)
path2 = format(path2)
if os.path.isdir(path1):
deepOverride(path1, path2)
continue
fileOverride(path1, path2)
# 备份后深度覆盖文件夹
def backupOverride(src, tgt, bk):
assert (os.path.isdir(src))
if os.path.exists(tgt):
folder = os.path.basename(tgt)
to = os.path.join(bk, folder)
to = format(to)
deepOverride(tgt, to)
deepRemove(tgt)
deepOverride(src, tgt)