【问题标题】:Python: folder creation when copying filesPython:复制文件时创建文件夹
【发布时间】:2016-02-22 02:22:30
【问题描述】:

我正在尝试创建一个 shell 脚本,它将文件从一台计算机(员工的旧计算机)复制到另一台计算机(员工的新计算机)。感谢这里可爱的人,我已经可以复制文件了,但我遇到了一个问题 - 如果我要从这个有 2 个文件的目录出发:

C:\Users\specificuser\Documents\Test 文件夹 ....到这个目录... C:\用户\特定用户\桌面 ...我看到文件显示在桌面上,但没有创建这些文件所在的文件夹(测试文件夹)。

这是我正在使用的复制功能:

#copy function
def dir_copy(srcpath, dstpath):
    #if the destination path doesn't exist, create it
    if not os.path.exists(dstpath):
        os.makedir(dstpath)
    #tag each file to the source path to create the file path
    for file in os.listdir(srcpath):
        srcfile = os.path.join(srcpath, file)
        dstfile = os.path.join(dstpath, file)
        #if the source file path is a directory, copy the directory
        if os.path.isdir(srcfile):
            dir_copy(srcfile, dstfile)
        else: #if the source file path is just a file, copy the file
            shutil.copyfile(srcfile, dstfile)

我知道我需要在目标上创建目录,但我不太确定该怎么做。

编辑:我发现我有一个类型(os.makedir 而不是 os.mkdir)。我对其进行了测试,它创建了应有的目录。但是我希望它从它开始的地方创建一个级别的目录。例如,在测试文件夹中有子测试文件夹。它已创建子测试文件夹但不会创建测试文件夹,因为测试文件夹不是 dstpath 的一部分。这有意义吗?

【问题讨论】:

  • @PaulK。我已经将其作为该函数所做的第一件事。但是,我认为问题在于我的“目标”是桌面 - 我没有将 Desktop\Test 文件夹指定为目标,因此永远不会创建测试文件夹。
  • 抱歉,我没看到。所以问题是副本不能递归工作?
  • @PaulK.I 编辑了我的原始帖子,但真正的问题是我希望它比我开始的地方更上一层楼。如果我将 Documents\Test 文件夹中的所有内容移至桌面,我希望它也创建 Desktop\Test 文件夹,即使从技术上讲我没有将目标指定为 Desktop\Test 文件夹,但我指定了桌面。

标签: python directory copy


【解决方案1】:

您可能想查看shutil.copytree()。它执行递归复制功能,包括您正在寻找的目录。因此,对于基本的递归副本,您只需运行:

shutil.copytree(srcpath, dstpath)

但是,为了完成将源目录复制到目标目录的目标,在此过程中在目标目录中创建源目录,您可以使用以下内容:

import os
import shutil

def dir_copy(srcpath, dstdir):
    dirname = os.path.basename(srcpath)
    dstpath = os.path.join(dstdir, dirname)
    shutil.copytree(srcpath, dstpath)

请注意,您的 srcpath 不得在末尾包含斜杠,这样才能正常工作。另外,加入目的目录和源目录名的结果不能已经存在,否则copytree会失败。

【讨论】:

  • 我收到“访问被拒绝” - 有没有办法以提升权限或其他方式运行 shutil ?也许让用户输入计算机管理员的用户名和密码?
  • @MasterModnar 如果您以管理员权限运行脚本,则不应收到拒绝访问错误。不过,老实说,我对在 Windows 上编程 python 知之甚少。如果您收到写入错误,您可能会考虑更新目标文件夹的权限,而不是以管理员身份运行。您也可以except IOError,如果 errno 为 13(权限被拒绝),则可能使用不同的目标。
【解决方案2】:

这是文件复制的常见问题...您打算只复制文件夹的内容还是要复制文件夹本身。复制实用程序通常对此有一个标志,您也可以。我使用os.makedirs 以便同时创建任何中间目录。

#copy function
def dir_copy(srcpath, dstpath, include_directory=False):
    if include_directory:
        dstpath = os.path.join(dstpath, os.path.basename(srcpath))
    os.makedirs(dstpath, exist_ok=True)
    #tag each file to the source path to create the file path
    for file in os.listdir(srcpath):
        srcfile = os.path.join(srcpath, file)
        dstfile = os.path.join(dstpath, file)
        #if the source file path is a directory, copy the directory
        if os.path.isdir(srcfile):
            dir_copy(srcfile, dstfile)
        else: #if the source file path is just a file, copy the file
            shutil.copyfile(srcfile, dstfile)

【讨论】:

  • 'include_directory' 对函数有什么作用,为什么将其设置为 'False'?另外,你能向我解释一下“exist_ok=True”吗?
  • include_directory 更改算法以在复制文件之前在目标中创建srcpath(“临时文件夹”)的基本名称。 os.makedirs 并将创建多个子目录(假设 dstpath 是需要创建的“C:\Users\specificuser\Desktop\test1\copiedfiles”)和exist_ok 如果目录已经存在则不会引发错误(没有需要 os.path.exists 测试)。在第一次调用时,设置include_directory=True,但后面的递归调用不需要它。
【解决方案3】:
import shutil
import os

def dir_copy(srcpath, dstpath):
    try:
        shutil.copytree(srcpath, dstpath)
    except shutil.Error as e:
        print('Directory not copied. Error: %s' % e)
    except OSError as e:
        print('Directory not copied. Error: %s' % e)


dir_copy('/home/sergey/test1', '/home/sergey/test2')

【讨论】:

    【解决方案4】:

    我使用这个脚本来备份(复制)我的工作文件夹。它将跳过大文件,保留文件夹结构(层次结构)并在目标文件夹不存在时创建它们。

    import os
    import shutil
    
    
    for root, dirs, files in os.walk(the_folder_copy_from):
       for name in files:
          if os.path.getsize(os.path.join(root, name))<10*1024*1024:
              target=os.path.join("backup", os.path.relpath(os.path.join(root, name),start=the_folder_copy_from))
              print(target)
              os.makedirs(os.path.dirname(target),exist_ok=True)
              shutil.copy(src=os.path.join(root, name),dst=target)
    
    print("Done")
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 2019-05-17
      相关资源
      最近更新 更多