Python-перемещение и перезапись файлов и папок
У меня есть каталог, "DST каталог", который имеет файлы и папки в нем, и у меня есть "src каталог", который также имеет файлы и папки в нем. То, что я хочу сделать, это переместить содержимое "src Directory" в "DST Directory" и перезаписать любые файлы, которые существуют с тем же именем. Так например ' Src Directoryfile.txt ' необходимо переместить в каталог Dst и перезаписать существующий файл.формат 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.removeдля удаления существующих файлов.
у меня была похожая проблема. Я хотел переместить файлы и структуры папок и перезаписать существующие файлы, но не удалять ничего, что находится в структуре папок назначения.
Я решил это с помощью
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)
Comments