Python-перемещение и перезапись файлов и папок
У меня есть каталог "DST Directory", в котором есть файлы и папки, и у меня есть "src Directory", в котором также есть файлы и папки. То, что я хочу сделать, это переместить содержимое "каталога src" в "каталог Dst" и перезаписать любые файлы, которые существуют с тем же именем. Так, например, ' Src Directoryfile.txt "необходимо переместить в" DST Directory " и перезаписать существующий файл.формат txt. То же самое относится к некоторым папкам, перемещая папку и объединяя содержимое с той же папкой в папка 'ДСТ'
в настоящее время я использую shutil.переместить, чтобы переместить содержимое src в dst, но это не будет делать, если файлы уже существуют, и он не будет объединять папки; он просто поместит папку внутри существующей папки.
Update: чтобы сделать вещи немного яснее; то, что я делаю, это распаковка архива В КАТАЛОГ Dst, а затем перемещение содержимого каталога Src туда и резипинг, эффективное обновление файлов в zip-архиве. Это будет повторено для добавления новых файлов или новых версий файлов и т. д. Поэтому он должен перезаписать и слияния
решено: я решил свою проблему с помощью distutils.dir_util.copy_tree (src, dst), это копирует папки и файлы из каталога src в каталог dst и перезаписывает/объединяет, где необходимо. Надеюсь, это поможет некоторым людям!
надеюсь, что это имеет смысл, спасибо!
6 ответов
использовать copy()
вместо этого, который готов переписать файлы назначения. Если вы хотите, чтобы первое дерево исчезло, просто rmtree()
это отдельно, как только вы закончите перебирать его.
http://docs.python.org/library/shutil.html#shutil.copy
http://docs.python.org/library/shutil.html#shutil.rmtree
обновление:
сделать os.walk()
на исходном дереве. Для каждого каталога проверьте, существует на стороне назначения, и os.makedirs()
его, если он отсутствует. Для каждого файла, просто shutil.copy()
и файл будет создан или перезаписан, в зависимости от ситуации.
это будет проходить через исходный каталог, создавать любые каталоги, которые еще не существуют в целевом каталоге, и перемещать файлы из исходного каталога в целевой каталог:
import os
import shutil
root_src_dir = 'Src Directory\'
root_dst_dir = 'Dst Directory\'
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_file, dst_dir)
все ранее существовавшие файлы будут удалены первыми (через os.remove
) перед заменой на соответствующий исходный файл. Любые файлы или каталоги, которые уже существуют в месте назначения, но не в источнике останутся нетронутыми.
поскольку ни один из вышеперечисленных не работал для меня, поэтому я написал свою собственную рекурсивную функцию. Вызов функция copyTree(dir1 и Директория dir2), чтобы объединить каталоги. Работать на нескольких платформах Linux и Windows.
def forceMergeFlatDir(srcDir, dstDir):
if not os.path.exists(dstDir):
os.makedirs(dstDir)
for item in os.listdir(srcDir):
srcFile = os.path.join(srcDir, item)
dstFile = os.path.join(dstDir, item)
forceCopyFile(srcFile, dstFile)
def forceCopyFile (sfile, dfile):
if os.path.isfile(sfile):
shutil.copy2(sfile, dfile)
def isAFlatDir(sDir):
for item in os.listdir(sDir):
sItem = os.path.join(sDir, item)
if os.path.isdir(sItem):
return False
return True
def copyTree(src, dst):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isfile(s):
if not os.path.exists(dst):
os.makedirs(dst)
forceCopyFile(s,d)
if os.path.isdir(s):
isRecursive = not isAFlatDir(s)
if isRecursive:
copyTree(s, d)
else:
forceMergeFlatDir(s, d)
Если Вам также нужно перезаписать файлы с флагом только для чтения, используйте это:
def copyDirTree(root_src_dir,root_dst_dir):
"""
Copy directory tree. Overwrites also read only files.
:param root_src_dir: source directory
:param root_dst_dir: destination directory
"""
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
try:
os.remove(dst_file)
except PermissionError as exc:
os.chmod(dst_file, stat.S_IWUSR)
os.remove(dst_file)
shutil.copy(src_file, dst_dir)
у меня была похожая проблема. Я хотел переместить файлы и структуры папок и перезаписать существующие файлы, но не удалять ничего, что находится в структуре папок назначения.
Я решил это с помощью os.walk()
, рекурсивно вызывая мою функцию и используя shutil.move()
на файлы, которые я хотел перезаписать и папки, которые не существовали.
Он работает shutil.move()
, но с тем преимуществом, что существующие файлы только перезаписываются, но не удаляются.
import os
import shutil
def moverecursively(source_folder, destination_folder):
basename = os.path.basename(source_folder)
dest_dir = os.path.join(destination_folder, basename)
if not os.path.exists(dest_dir):
shutil.move(source_folder, destination_folder)
else:
dst_path = os.path.join(destination_folder, basename)
for root, dirs, files in os.walk(source_folder):
for item in files:
src_path = os.path.join(root, item)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_path, dst_path)
for item in dirs:
src_path = os.path.join(root, item)
moverecursively(src_path, dst_path)