我尝试遍历文件夹并根据文件扩展名创建文件夹,然后复制此文件夹中的所有相关文件。但出于意外原因,只复制了一个文件,并在下一个文件中切换脚本。我认为基础很好,因为正确创建了文件夹并复制了一个文件。那么为什么所有其他人都没有被复制?
有人可以帮我弄清楚原因吗?
import os
import shutil
dir = "/home/user/Documents/utils/testFindAndCopy"
target = "/home/user/Documents/utils/result"
def createDir(target):
os.makedirs(str(target))
def copyFiles(file, target):
shutil.copy2(file, target)
for subdir, dirs, files in os.walk(dir):
for file in files:
filepath = subdir + os.sep + file
folderName = file.split('.')
targetDir = target + '/' + str(folderName[1])
try:
if os.path.exists(str(folderName)):
print(folderName[1])
print(targetDir)
print(filepath)
copyFiles(filepath, targetDir)
else:
createDir(str(targetDir))
copyFiles(filepath, targetDir)
print(folderName[1])
print(targetDir)
print(filepath)
except OSError, e:
if e.errno != 17:
raise
# time.sleep might help here
pass
答案 0 :(得分:1)
使用shutil.copytree(src, dst)
。
你甚至不必带着它走文件树。只需将顶级目录设置为源。
来自docs:
递归复制以src为根的整个目录树,返回目标目录。目标目录(由dst命名)必须不存在;它将被创建以及缺少父目录。使用copystat()复制目录的权限和时间,使用shutil.copy2()复制单个文件。
答案 1 :(得分:1)
这里有几个错误。文件和目录操作很棘手,你需要非常小心。
您应该使用os.path.join来构建文件路径。
在“。”上拆分文件名时,返回的值是列表,而不是字符串。这是你的变量folderName
- 不是一个精心挑选的名字。您的表达式os.path.exists(str(folderName))
将始终为False,因为str()函数不会重新构建列表中的简单字符串。
文件名可以包含多个点。当您使用folderName[1]
作为目录名时,您假设在您的情况下没有这样的文件名。
如果您使用folderName[-1]
,您将始终获得文件名的最后一部分。
如果在已存在的目录上调用mkdir / makedirs,则会在此时引发OSError异常。然后不会进行文件复制。
shutil.copy2复制一个文件,即使您通过名为copyFiles
的函数调用它。
你捕获一个OSError,但除非是17,否则不对它做任何事情,不管是什么。因此,您不会知道您的脚本是否正在捕获错误。
你希望你的主循环是这样的:
for subdir, dirs, files in os.walk(dir):
for file in files:
filepath = os.path.join(subdir, file)
folderName = file.split('.')
targetDir = os.path.join(target, folderName[-1])
try:
print(targetDir, filepath, os.path.exists(targetDir))
if not os.path.exists(targetDir):
createDir(targetDir)
shutil.copy2(filepath, targetDir)