zoukankan      html  css  js  c++  java
  • Python 同步文件夹

    将基础文件夹下的文件,按照目录结构,同步到目标文件夹下,如果目标文件夹下没有相应的目录结构,就创建目录,然后再将基础文件夹下的文件同步到相应的目录下去。

    import os
    import shutil
    import time
    import hashlib
    
    # MD5值
    def getMD5(path):
        f=open(path,'rb')
        d5 = hashlib.md5()      #生成一个hash的对象
        with open(path,'rb') as f:
            while True:
                content = f.read(40960)
                if not content:
                    break
                d5.update(content)   # 每次读取一部分,然后添加到hash对象里
        # print('MD5 : %s' % d5.hexdigest())
        return d5.hexdigest()        # 打印16进制的hash值
    
    # 装饰器,计时用的
    def timer(func):   # 高阶函数:以函数作为参数
        def deco(*args,**kwargs):    # 嵌套函数,在函数内部以 def 声明一个函数,接受 被装饰函数的所有参数
            time1 = time.time()
            func(*args,**kwargs)
            time2 = time.time()
            print('Elapsed %ss
    ' % round(time2-time1,2))
        return deco    # 注意,返回的函数没有加括号!所以返回的是一个内存地址,而不是函数的返回值
    
    @timer
    def compare(baseFolder,targetFolder,content_compare='y'):
        '''
        :param baseFolder:   基础文件夹,将基础文件夹中的文件按照相应的目录结构同步到目标文件夹中。
        :param targetFolder: 目标文件夹
        :content_compare: 是否比对两个文件的内容,默认比对,防止文件内容有更改。参数值如果不是'y',则不比对内容,只判断目标文件夹是否有同名文件,有就跳过,没有就复制过去。
        '''
        n = 0
        for path,subpath,files in os.walk(baseFolder):
            for file in files:
                # 获取文件的绝对路径
                absPath = os.path.join(path,file)
                # 文件的后半截路径,即文件的相对路径
                file_path = absPath.replace(baseFolder,'')
                # 去掉路径前面的
                if file_path[:1] == '\':
                    file_path = file_path[1:]
    
                # 替换目录末尾的
                if targetFolder[:1] == '\':
                    targetFolder = targetFolder[1:]
    
                # 判断目标文件夹是否有相应的文件
                filePath = os.path.join(targetFolder,file_path)
                
                # 创建文件夹路径
                fileFolder = os.path.dirname(filePath)
                
                # 如果目标文件夹不存在此文件
                if not os.path.exists(filePath):
                    os.makedirs(fileFolder,exist_ok=True)
                    # 复制文件
                    shutil.copy(absPath,fileFolder)
                    print(f'
         {absPath}   -------------->   {filePath}')
                else: # 如果目标文件夹已经存在某文件
                    # 如果要对比两个文件的内容
                    if content_compare == 'y':
                        # 先对比两个文件的修改时间(谁的时间越大,代表谁的内容越新)
                        baseTime = os.stat(absPath).st_mtime
                        targetTime = os.stat(filePath).st_mtime
                        if baseTime-targetTime > 0:
                            # 比了时间,再比一下MD5。如果MD5也不同,就将这个时间最新的文件复制过去
                            baseMD5 = getMD5(absPath)
                            targetMD5 = getMD5(filePath)
                            if baseMD5 != targetMD5:
                                os.unlink(filePath)
                                shutil.copy(absPath,fileFolder)
                                print(f'
         {absPath}   -------------->   {filePath}')
                            else:
                                # MD5相同,而目标文件夹中的时间又小,就将修改时间改大,防止下次运行此脚本时再对比一遍MD5,浪费时间
                                # 修改文件的访问和修改时间,改成当前系统时间
                                os.utime(filePath)
                n+=1
                print("
    %s:  Has scanned %s files. "%(baseFolder,n),end='' )
    
    if __name__ == '__main__':
        print('----------Copying the files of BaseFolder to TargetFolder.----------
    ')
        base = input('Input base folder:')
        target = input('Input target folder:')
        # 当有相同文件时,是否对比文件内容,把最新的同步过去,适用于经常变动的文件,如脚本,文档
        content_compare = input('Compare content? y/n: ').lower()
        if base == '':
            compare(r'D:备份',r'G:备份')
            compare(r'D:software',r'G:software')
            compare(r'E:文档',r'G:document')
        else:
            compare(base,target,content_compare)
  • 相关阅读:
    ES6中关于数据类型的拓展:Symbol类型
    ES里关于数组的拓展
    ES里关于对象的拓展
    ES6里关于函数的拓展(三)
    ES6里关于函数的拓展(二)
    ES6里关于函数的拓展(一)
    ES6里关于正则表达式的拓展
    ES6里关于模板字面量的拓展
    Android之怎样实现滑动页面切换【Fragment】
    java quartz的使用,做时间轮询调用 CronTrigger
  • 原文地址:https://www.cnblogs.com/wztshine/p/12116843.html
Copyright © 2011-2022 走看看