为shutil.copy文件创建目标路径

时间:2010-05-08 11:00:24

标签: python

如果b/c/中不存在./a/b/c之类的路径,则shutil.copy("./blah.txt", "./a/b/c/blah.txt")会抱怨目的地不存在。创建目标路径并将文件复制到此路径的最佳方法是什么?

8 个答案:

答案 0 :(得分:25)

使用os.makedirs创建目录树。

答案 1 :(得分:19)

在使用它之前,我使用与此类似的东西来检查目录是否存在。

if not os.path.exists('a/b/c/'):
    os.mkdir('a/b/c')

答案 2 :(得分:12)

EAFP方式,避免比赛和不需要的系统调用:

import errno
import os
import shutil

src = "./blah.txt"
dest = "./a/b/c/blah.txt"
# with open(src, 'w'): pass # create the src file
try:
    shutil.copy(src, dest)
except IOError as e:
    # ENOENT(2): file does not exist, raised also on missing dest parent dir
    if e.errno != errno.ENOENT:
        raise
    # try creating parent directories
    os.makedirs(os.path.dirname(dest))
    shutil.copy(src, dest)

答案 3 :(得分:11)

总结来自给定答案和评论的信息:

对于使用os.mkdirs的{​​{1}}之前的python 3.2 + copy

exist_ok=True

对于python< 3.2 os.makedirs(os.path.dirname(dest_fpath), exist_ok=True) shutil.copy(src_fpath, dest_fpath) 抓住os.mkdirs后再次尝试复制:

IOError

虽然您可以更明确地检查try: shutil.copy(src_fpath, dest_fpath) except IOError as io_err: os.makedirs(os.path.dirname(dest_fpath) shutil.copy(src_fpath, dest_fpath) 和/或在errno之前检查路径exists,但恕我直言这些片段在简单性和功能性之间取得了很好的平衡。

答案 4 :(得分:2)

我如何使用split来将dir从路径中取出

dir_name, _ = os.path.split("./a/b/c/blah.txt")

然后

os.makedirs(dir_name,exist_ok=True)

最后

shutil.copy("./blah.txt", "./a/b/c/blah.txt")

答案 5 :(得分:2)

对于3.4 / 3.5 +,您可以使用pathlib

Path.mkdir(mode = 0o777,parents = False,exist_ok = False)


因此,如果可能要创建多个目录,并且它们可能已经存在:

pathlib.Path(dst).mkdir(parents=True, exist_ok=True)

答案 6 :(得分:1)

我的五美分将是下一个方法:

# Absolute destination path.
dst_path = '/a/b/c/blah.txt'
origin_path = './blah.txt'
not os.path.exists(dst_path) or os.makedirs(dst_path)
shutil.copy(origin_path, dst_path)

答案 7 :(得分:0)

许多其他答案适用于旧版本的 Python,尽管它们可能仍然有效。

如果您使用的是 Python 3.3 或更新版本,我们可以捕获 FileNotFoundError 而不是 IOError。我们还想区分目标路径不存在和源路径不存在。我们想吞下前一个异常,而不是后者。

最后,请注意 os.makedirs() 递归地一次创建一个丢失的目录——这意味着它不是一个原子操作。如果您有多个线程或进程可能尝试同时创建相同的目录树,您可能会看到意外行为。

def copy_path(*, src, dst, dir_mode=0o777, follow_symlinks: bool = True):
    """
    Copy a source filesystem path to a destination path, creating parent
    directories if they don't exist.

    Args:
        src: The source filesystem path to copy. This must exist on the
            filesystem.

        dst: The destination to copy to. If the parent directories for this
            path do not exist, we will create them.

        dir_mode: The Unix permissions to set for any newly created
            directories.

        follow_symlinks: Whether to follow symlinks during the copy.

    Returns:
        Returns the destination path.
    """
    try:
        return shutil.copy(src=src, dst=dst, follow_symlinks=follow_symlinks)
    except FileNotFoundError as exc:
        if exc.filename == dst and exc.filename2 is None:
            parent = os.path.dirname(dst)
            os.makedirs(name=parent, mode=dir_mode, exist_ok=True)
            return shutil.copy2(
                src=src,
                dst=dst,
                follow_symlinks=follow_symlinks,
            )
        raise