Python快速比较文件、深度罗列文件夹、深度比较文件夹、强制覆盖文件内容、深度覆盖文件夹、备份覆盖文件夹

参考资料

《Python遍历文件夹》

《Python List交集、并集、差集》 

 

# !/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)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值