此代码应在定义的文件夹列表中备份新文件。它应该每小时完成一次,另一个代码清除旧文件的目标文件夹。
首先我定义时间,如果文件夹中的任何文件超过 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)