0

此代码应在定义的文件夹列表中备份新文件。它应该每小时完成一次,另一个代码清除旧文件的目标文件夹。

首先我定义时间,如果文件夹中的任何文件超过 3 天,它就不会复制它。

Source_pole 是要从中复制的文件列表。

Destination_root 是要复制到的目标,其中 driveName 是备份介质的盘符。

我还想从 C:\folder 中仅复制 *.txt 文件,这就是定义 files_pattern 的原因。但现在我只想复制工作正常。

该功能工作正常,它只复制那些新文件。

但是它从 source_pole 中获取所有匹配的文件,并将它们全部复制到destination_root 中而没有文件夹,但我希望它们在源中的确切文件夹中。

我知道 shutil.copytree 会更好,但这应该是每小时运行一次的备份脚本,我不知道如何处理文件夹已经存在的错误。

os.walk(root_path) 返回列表中源文件的目录名,如果该文件夹不存在,那么我需要 os.makedirs(那个文件夹),对吗?但是怎么做?

看来我正在写类似于 shutil.copytree 的东西(http://docs.python.org/2/library/shutil.html#copytree-example

cas_dny = 3
#prepocitej dny na hodiny a pak na sekundy
cas_sekundy = cas_dny * 24 * 3600

source_pole = [
'c:\\folder\\export',
'c:\\folder\\log',
'c:\\folder\\import',
]

destination_root = driveName+'\autobackup'

excluded_subdirs = ['_backup'] # subdir to exclude from copy
files_patterns_root = ['*.txt']
files_patterns = ['*.*']

def CopyFiles ():
    for root_path in source_pole:
        for root, dirnames, filenames in os.walk(root_path):
            for dir in excluded_subdirs:
                if dir in dirnames:
                    dirnames.remove(dir) # remove the dir from the subdirs to visit
            for filename in filenames:
                vlastnosti = os.stat(os.path.join(root,filename))
                cas_pristupu = vlastnosti.st_mtime
                now = time.time()
                timedelta = now - cas_pristupu
                if timedelta < cas_sekundy
                    print 'Soubor', os.path.join(root,filename), u'je mladší jak', cas_dny ,u'dny | Tento soubor zkopíruju\n---'
                    for pattern in files_patterns:
                        for thefile in fnmatch.filter(filenames, pattern): # filter the files to copy
                            shutil.copy2(os.path.join(root, thefile), destination_root) #copy file

EDIT1:对于:

 source_pole = [
'c:\\folder\\bin\\export',
'c:\\folder\\bin\\log',
'c:\\folder\\bin\\import',
]

作品

for dir in excluded_subdirs:
    destionatin_path = os.path.join(destination_root, os.path.relpath(root)).replace ('..\..\..\\','')
    try:
        os.makedirs(os.path.join(destination_root, os.path.relpath(root)).replace ('..\..\..\\',''))
    except OSError as e:
        print e
...
...
...
shutil.copy2(os.path.join(root, thefile), destination_path) #copy file

但是如果我在 source_pole 中选择了另一个文件路径,我将不得不在替换时更改字符串...

必须有更好的方法在目的地创建相同的树结构,这很混乱。

EDIT2:所以我只是编辑了shutil.copytree函数并添加了if文件的年龄,匹配模式,不覆盖相同的文件并将只读文件写入可写。它对我的使用很好,只是它不是很快(大约 2MB/s),但我对它不满意,因为在 shutil.py 中有“考虑这个示例代码而不是终极工具”。在copytree函数中。

更大的问题是,当函数在打开 *.docx 文件等时偶然发现像 ~$* 文件这样隐藏的文件时,它以错误 13: Permission Denied 结尾,我无法排除此错误。我只是在忽略参数中使用 shutil.ignore_patterns('~$*') 来避免它。知道错误可能在哪里吗?

顺便说一句:我想让文件夹参数仅在某些级别复制文件,但我能想到的唯一方法是在 src 中计算 '\' ,当它达到某个 '\' 计数然后停止。有更好的想法吗?

#for logging purposes
copiedfiles = 0

def kopytree(src, dst, pattern, folders=True, symlinks=False, ignore=None):
    global copiedfiles
    global porovnej
    # if src does not exist, function ends
    if not os.path.exists(src):
        print u'Neexistující složka'
        return
    # names writes list of dirs and files in src
    names = os.listdir(src)
    errors = []
    # if for deleting unwanted in names
    if ignore is not None:
        ignored_names = ignore(src, names)
    else:
        ignored_names = set()
    for name in names:
        if name in ignored_names:
            continue
        # fullpaths
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        # get last modified time
        try:
            cas_pristupu = os.stat(srcname).st_mtime
        except IOError as e:
            print e
            print 'Nepodarilo se zjistit vlastnosti souboru'
            logger.warning('U souboru %s se nepodarilo zjistit vlastnoti souboru' % srcname)
        now = time.time()
        # timedelta = age of file in s
        timedelta = now - cas_pristupu
        if timedelta < cas_sekundy:
            # if file is younger then cas_sekundy continue in copy
            try:
                os.makedirs(dst)
            except OSError as e:
                pass
            # if file already exists and they match, then dont overwrite them
            porovnej = False
            try:
                if os.path.isfile(srcname) and os.path.exists(dstname):
                    porovnej = filecmp.cmp(srcname,dstname)
            except WindowsError as e:
                pass
            except IOError as f:
                print f
            # if they match, end
            if porovnej == True:
                print '\nSoubory', srcname,'|', dstname,' se zdaji byt stejne'
                del porovnej
                continue
            # if they dont, copy
            else:
                try:
                    if symlinks and os.path.islink(srcname):
                        linkto = os.readlink(srcname)
                        os.symlink(linkto, dstname)
                    # if folders=True then copy also folders
                    elif os.path.isdir(srcname) and folders:
                        kopytree(srcname, dstname, pattern, folders, symlinks, ignore)
                    # pokud souhlasi s dodanym filtrem, tak kopiruje
                    elif fnmatch.fnmatch(srcname, pattern):
                        copiedfiles += 1
                        print u'Kopíruji soubor', srcname, 'do', dstname
                        shutil.copy2(srcname, dstname)
                # XXX What about devices, sockets etc.?
                except (IOError, os.error) as why:
                    logger.warning('Soubor %s se nepodarilo zkopirovat' % srcname)
                    errors.append((srcname, dstname, str(why)))
                # catch the Error from the recursive copytree so that we can
                # continue with other files
                except Error as err:
                    errors.extend(err.args[0])
                # if source file is read only, then write them as writable so they could be deleted later
                try:
                    fileAtt = os.stat(srcname)[stat.ST_MODE]
                    if not fileAtt & stat.S_IWRITE:
                        logger.info ('Soubor %s je ke cteni, na cilove slozce ho udelam zapisovatelnym' % srcname)
                        print 'zdrojovy soubor je ke cteni, u ciloveho ho udelam zapisovatelnym'
                        os.chmod(dstname, stat.S_IWRITE)
                except IOError as e:
                    print e
    #copies permissions stats
    try:
        shutil.copystat(src, dst)
    except WindowsError:
        # can't copy file access times on Windows
        pass
    except OSError as why:
        errors.extend((src, dst, str(why)))
    if errors:
        raise Error(errors)
4

1 回答 1

0

尝试这个:

dest_path = os.path.join(destination_root, root)
os.makedirs(dest_path)
shutil.copy2(os.path.join(root, thefile), dest_path)
于 2013-11-05T10:06:25.743 回答