このコードは、定義されたフォルダーのリストにある新しいファイルをバックアップする必要があります。これは 1 時間ごとに実行する必要があり、別のコードが古いファイルのターゲット フォルダーをクリアします。
最初に時間を定義します。フォルダー内のファイルが 3 日より古い場合、それはコピーされません。
Source_pole は、コピー元のファイルのリストです。
Destination_root はコピー先のターゲットです。ここで、driveName はバックアップ メディアの文字です。
また、C:\folder から *.txt ファイルだけをコピーしたいので、files_pattern が定義されています。しかし、今はコピーして問題なく動作させたいだけです。
関数は問題なく動作し、それらの新しいファイルだけをコピーします。
しかし、一致するsource_poleからすべてのファイルを取得し、それらをすべてフォルダーなしでdestination_rootにコピーしますが、ソースと同じように正確なフォルダーにそれらをコピーします。
shutil.copytree の方がうまく機能することはわかっていますが、これは 1 時間ごとに実行されるバックアップ スクリプトであると想定されており、フォルダーが既に存在するというエラーに対処する方法がわかりません。
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関数を編集し、ファイルの年齢、パターンの一致、同じファイルを上書きせず、読み取り専用ファイルを書き込み可能として書き込む場合に追加しました。それは私の使用には適していますが、あまり高速ではありません (約 2MB/秒) だけですが、shutil.py に「究極のツールではなく、このサンプル コードを検討してください」という記述があるため、満足していません。コピーツリー関数で。
もっと大きな問題は、関数が *.docx ファイルを開くときに ~$* ファイルのように隠されているファイルにつまずいたときです。エラー 13: Permission Denied で終了し、このエラーを除外できませんでした。それを避けるために、ignore パラメータで 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)