【问题标题】:Copy file if it doesn't already exist [duplicate]如果文件不存在则复制文件[重复]
【发布时间】:2014-01-04 03:15:35
【问题描述】:

我是 python 的新手,我想知道如何将文件从一个位置复制并粘贴到另一个位置,首先检查复制的文件是否存在于目标文件夹中?

我想检查文件是否存在的原因是这个脚本将被放在任务调度程序上并按设定的时间表运行,所以我不想每次都复制所有内容,只是那些不复制的文件'目标文件夹中不存在?

提前致谢!

【问题讨论】:

  • os.path.exists(/some/path/)
  • FWIW,我认为处理文件创建/删除/使用的方法几乎总是比os.path.exists 更好。在大多数情况下,还有另一个模块可以更优雅地处理它(正如我在使用 glob 比较两个列表的答案中使用的那样),如果没有,那么 try/catch 可以更好地防止竞争条件。我想不出我写过的任何使用os.path.exists 的脚本我无法重写以使用具有更好功能的glob
  • @adsmith 除非您有一些安全问题,否则没有理由不使用os.path.exist
  • 使用 rsync 代替 cp

标签: python file file-io


【解决方案1】:
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 异常。我相信如果您没有对源目录的读取权限,glob 只会返回一个空列表(这反过来又不会通过“For”循环提供任何内容,因此您不会有任何错误)。

编辑:显然 glob 不像我记得的那样工作,对此感到抱歉。

【讨论】:

  • 在这种情况下,我不想复制整个文件夹,我想复制文件夹内的内容,PDF 文件。
  • 这就是它的作用——抱歉我不清楚。 glob.glob 根据您提供的一些参数返回文件夹内容列表(例如,glob.glob(TARG_DIR+"\\*.pdf") 将返回 TARG_DIR 中扩展名为 PDF 的文件列表)。
  • 这是我尝试过的,但出现错误:import glob import os.path import shutil SRC_DIR = "C:\\Users\\mboyle\\Documents\\Source" TARG_DIR = "C:\\Users\\mboyle\\Documents\\Target" for file in glob.glob(SRC_DIR): if file not in glob.glob(TARG_DIR): shutil.copy(file,TARG_DIR) else: print "exists"
  • 第 10 行,即shutil.copy(file,TARG_DIR)。我需要指定文件类型 (.pdf) 吗?
  • 没有。你能帮我粘贴堆栈跟踪吗?
【解决方案2】:

在 Python 中,经常可以看到在运行代码时会遇到错误,称为exceptions。为此,已部署try/catch

这是我日常使用的一段代码,用于清除目录中的文件,如果文件不存在则跳过。

def 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 可用于捕捉任何异常,也可用于捕捉specific ones。我有OSError 潦草地写了但仔细阅读以确保那是你想要的。如果您在 catch 中有特定错误并且系统返回错误类型的错误,您的 try/catch 将无法按照您希望的方式工作。所以,请确定。在最好的情况下,一般。

编码愉快!

编辑:值得注意的是,这个try/catch 系统是一种非常Pythonic 的处理方式。 try/catch 非常简单且受欢迎,但您的情况可能需要不同的东西。

编辑:我不确定这是否值得注意,但我意识到我的回答并没有直接告诉您 如何 检查文件是否存在。相反,它假定它没有并继续操作。如果你遇到问题(即它存在并且你需要覆盖),你可以让它自动跳过整个事情并进入下一个问题。同样,这只是完成相同任务的众多方法之一。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 2016-01-22
  • 2014-12-10
  • 1970-01-01
  • 2022-11-17
  • 2018-03-27
  • 2018-04-19
相关资源
最近更新 更多