Python - перемещение и перезапись файлов и папок
У меня есть каталог "Dst Directory" , в котором есть файлы и папки, и у меня есть "src Directory", в котором также есть файлы и папки. То, что я хочу сделать, - переместить содержимое "src Directory" в "Dst Directory" и перезаписать anyfiles, которые существуют с тем же именем. Так, например, "Src Directory\file.txt" необходимо перенести в "Dst Directory" и перезаписать существующий файл .txt. То же самое относится к некоторым папкам, перемещению папки и объединению содержимого с той же папкой в каталоге dst
В настоящее время я использую shutil.move для перемещения содержимого src в dst, но он не будет работать, если файлы уже существуют и не будут слиявать папки; он просто поместит папку в существующую папку.
Обновление: сделать вещи немного яснее; То, что я делаю, - это распаковать архив в каталог Dst, а затем переместить содержимое каталога Src и выполнить распаковку, эффективно обновляя файлы в zip-архиве. Это будет повторяться для добавления новых файлов или новых версий файлов и т.д., Поэтому необходимо перезаписать и слить
Решено: я решил проблему, используя distutils.dir_util.copy_tree (src, dst), это копирует папки и файлы из каталога src в каталог dst и перезаписывает/объединяет там, где это необходимо. Надеюсь, что это поможет некоторым людям!
Надеюсь, что это имеет смысл,
спасибо!
Ответы
Ответ 1
Вместо этого используйте copy()
, который готов перезаписать файлы назначения. Если вы хотите, чтобы первое дерево исчезло, просто rmtree()
его отдельно, как только вы закончите над ним.
http://docs.python.org/library/shutil.html#shutil.copy
http://docs.python.org/library/shutil.html#shutil.rmtree
Update:
Сделайте os.walk()
над деревом источника. Для каждого каталога проверьте, существует ли он на стороне назначения, и os.makedirs()
, если он отсутствует. Для каждого файла просто shutil.copy()
и файл будет создан или перезаписан, в зависимости от того, что подходит.
Ответ 2
Это будет проходить через исходный каталог, создавать любые каталоги, которые еще не существуют в каталоге назначения, и перемещать файлы из источника в каталог назначения:
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
). Любые файлы или каталоги, которые уже существуют в месте назначения, но не в источнике, остаются нетронутыми.
Ответ 3
Поскольку ни одно из вышеперечисленных не работало для меня, поэтому я написал свою собственную рекурсивную функцию. Вызовите функцию 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)
Ответ 4
Если вам также необходимо перезаписать файлы с флагом только для чтения, используйте это:
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)
Ответ 5
Посмотрите на os.remove
, чтобы удалить существующие файлы.
Ответ 6
У меня была аналогичная проблема. Я хотел переместить файлы и структуры папок и перезаписать существующие файлы, но не удалить ничего, что находится в структуре папок назначения.
Я решил его с помощью 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)