我对Python比较新,想知道如何在复制文件到另一个位置之前,先检查该文件是否已存在于目标文件夹中?
我想要检查文件是否存在的原因是,该脚本将被放置在任务计划程序中并按照预定计划运行,因此我不想每次都复制所有文件,只需复制目标文件夹中不存在的文件即可。
提前感谢您!
import glob
import os.path
import shutil
SRC_DIR = #your source directory
TARG_DIR = #your target directory
GLOB_PARMS = "*" #maybe "*.pdf" ?
for file in glob.glob(os.path.join(SRC_DIR, GLOB_PARMS)):
if file not in glob.glob(os.path.join(TARG_DIR, GLOB_PARMS)):
shutil.copy(file,TARG_DIR)
else:
print("{} exists in {}".format(
file,os.path.join(os.path.split(TARG_DIR)[-2:])))
# This is just a print command that outputs to console that the
# file was already in directory
我假设您试图使用这个命令发送整个文件夹,否则 glob
使用的是非常易于理解的接口。 glob.glob("*.txt")
将抓取所有 .txt 扩展名的文件等等。调整它以符合您的要求不应该太难。
需要注意的是,文件复制通常涉及竞争条件。基本上,在检查文件是否不在 TARG_DIR (if file not in glob.glob(TARG_DIR)
) 并将其实际复制到那里 (shutil.copy(file,TARG_DIR)
) 之间会有时间流逝。在这段时间内,文件可能会出现在那里,这将导致 shutil.copy
覆盖该文件。如果这不是您想要的功能,那么您应该考虑使用其他方法。我不知道有没有一个好方法可以尝试复制文件,但如果该文件已经存在,则返回异常。
正如另一个答案提到的那样,Try/Except 块在这里也可能很有用,如果在运行脚本时可能没有写入目录的访问权限。如果是这种情况,shutil.copy
将返回一个 IOError
异常。我相信如果您没有读取源目录的访问权限(反过来将通过 "For" 循环不传递任何内容,因此您不会有任何错误),则 glob 将只返回一个空列表。
编辑:显然 glob 的工作方式与我记得的不同,对此感到抱歉。
glob.glob
根据您提供的一些参数返回文件夹内容的列表(例如,glob.glob(TARG_DIR+"\\*.pdf")
将返回 TARG_DIR 中扩展名为 PDF 的文件列表)。 - Adam Smithshutil.copy(file,TARG_DIR)
。我需要指定文件类型(.pdf)吗? - mpboyleTraceback (most recent call last): File "C:\Users\mboyle\Desktop\CopyPaste.py", line 10, in <module> shutil.copy(file,TARG_DIR) File "C:\Python27\ArcGIS10.1\lib\shutil.py", line 116, in copy copyfile(src, dst) File "C:\Python27\ArcGIS10.1\lib\shutil.py", line 81, in copyfile with open(src, 'rb') as fsrc: IOError: [Errno 13] Permission denied: 'C:\\Users\\mboyle\\Documents\\Source'
- mpboyledef DeleteFile(Path_):
"""Deletes saved project AND its corresponding "files" folder."""
try: #deletes the folder
os.remove(Path_)
except OSError:
pass
try: #deletes the file, using some fancy python operations to arrive at the filename
shutil.rmtree(os.path.join(os.path.dirname(Path_),os.path.splitext(os.path.basename(Path_))[0])+"_files", True)
except OSError:
pass
这是一个检查文件是否存在的经典示例。在您的try
语句中,您可以尝试复制文件而不是删除它。如果失败,则继续执行pass
,它只会跳过try/catch
块。
请注意,try/catch
可用于捕获任何异常,也可以用于捕获特定的异常。我已经写入了OSError
,但请仔细阅读以确保这是您想要的异常类型。如果您在catch
中有一个特定的错误,并且系统返回了错误类型不正确的错误,则您的try/catch
将无法按照您想要的方式工作。所以,请确保选择最好的情况下是通用的。
编码愉快!
编辑:值得注意的是,这个try/catch
系统是一种非常Pythonic的方法。 try/catch
非常简单和流行,但您的情况可能需要其他方法。
编辑:我不确定是否值得注意,但我意识到我的答案并没有直接告诉你如何检查文件是否存在。相反,它假设文件不存在并继续进行操作。如果遇到问题(即它存在且您需要覆盖),您可以使其自动跳过整个内容并转到下一个内容。同样,这只是完成相同任务的许多方法之一。
os.path.exists(/some/path/)
- yuvios.path.exist
。 - yuvi