Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Shutil尝试复制不包含';不存在_Python_Python 3.x_Directory_Shutil_Copying - Fatal编程技术网

Python Shutil尝试复制不包含';不存在

Python Shutil尝试复制不包含';不存在,python,python-3.x,directory,shutil,copying,Python,Python 3.x,Directory,Shutil,Copying,我试图复制Windows用户配置文件下的Documents文件夹,shutil.copytree(Documents,destination)部分工作。它会将文档复制到目标的根目录,在本例中为R:驱动器,并且还会尝试复制其他Windows特殊文件夹(我的音乐、我的图片等),即使它们不在“文档”下 import shutil def main(): try: user_profile = os.getenv("USERPROFILE") # Constr

我试图复制Windows用户配置文件下的Documents文件夹,
shutil.copytree(Documents,destination)
部分工作。它会将文档复制到目标的根目录,在本例中为
R:
驱动器,并且还会尝试复制其他Windows特殊文件夹(我的音乐、我的图片等),即使它们不在“文档”下

import shutil


def main():

   try:

       user_profile = os.getenv("USERPROFILE")

       # Construct a full path to the documents folder 
       documents = Path(user_profile).joinpath("Documents")

       # Destination for the Documents folder
       destination = Path("R:\\Test")

       shutil.copytree(documents, destination)            

   except (FileNotFoundError, shutil.Error) as error:
       print(error)


if __name__ == '__main__':
    main()
这是引发的异常的摘录:

[('C:\\Users\\ConsoleGeek\\Documents\\My Music', 'R:\\Test\\My Music', 
"[WinError 5] Access is denied: 'C:\\\\Users\\\\ConsoleGeek\\\\Documents\\\\My Music'")
...

文档下不存在这些文件夹,因此我不完全理解为什么
shutil
尝试复制这些特殊文件夹。如果我尝试复制用户配置文件下的常规文件夹,它会工作

我不太了解Windows系统,但你可以试着打电话给我

shutil.copytree(documents, destination, symlinks=True)
如果这些“特殊文件夹”是符号链接(或Windows等效的符号链接)。

要理解在试图复制
文档时为什么要尝试复制,我们必须首先查看隐藏的文件

使用cmd.exe:

如果我们打开
cmd.exe
并将目录更改为
Documents
,我们可以运行以查看所有文件夹(包括隐藏的文件夹)

使用Powershell

如果我们打开
powershell.exe
并键入,它将列出
文档
文件夹中的所有项目

注意:它不显示特殊文件夹

PS C:\Users\ConsoleGeek> Get-ChildItem -Force -File -Path .\Documents\


    Directory: C:\Users\ConsoleGeek\Documents


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a-hs-        10/4/2019   6:00 PM            402 desktop.ini
使用Python

我在VSCode中运行了以下代码:

def main():

    try:
        user_profile = os.getenv("USERPROFILE")
        documents = Path(user_profile).joinpath("Documents")

        for item in documents.iterdir():
            print(item)

    except (FileNotFoundError, shutil.Error) as error:
       print(error)

if __name__ == '__main__':
    main()


# Output:
C:\Users\ConsoleGeek\Documents\desktop.ini
C:\Users\ConsoleGeek\Documents\My Music
C:\Users\ConsoleGeek\Documents\My Pictures
C:\Users\ConsoleGeek\Documents\My Videos
使用文件资源管理器

如果我选择了显示隐藏文件的选项,则
文档
文件夹仍为空

递归复制

使用cmd.exe

使用
xcopy
命令和
/E
/H
开关,我们可以复制所有文件夹/文件,包括空的和隐藏的文件夹/文件

C:\Users\ConsoleGeek>xcopy Documents R:\Sync\Documents /E /H
Documents\desktop.ini
Access denied
Unable to create directory - R:\Sync\Documents\My Music
1 File(s) copied
复制的
1个文件
具有误导性,因为启用“显示隐藏文件”时,您可以验证未复制任何内容

使用Powershell

使用带有
-Recurse
开关的
Copy Item
cmdlet,我们得到一个拒绝访问错误,类似于
cmd.exe

这是错误消息的摘录

Copy-Item : Access to the path 'C:\Users\ConsoleGeek\Documents\My Music' is denied.
解决方案

使用cmd.exe

xcopy
具有
/Exclude:filename.txt
参数。您提供了一个包含要排除的文件夹/文件名的文件

My Music
My Pictures
My Video
desktop.ini
并将其与
xcopy
命令一起使用:

C:\Users\ConsoleGeek>xcopy Documents R:\Sync\Documents /E /H /EXCLUDE:filenames.txt
使用Powershell

-Exclude
参数与
-Recurse
参数不起作用,因此它只会复制空的My Music,My。。。文件夹。要从要复制的文件中排除它们,可以为
-exclude
参数提供通配符

Copy-Item -Path .\Documents\ -Destination "R:\Sync\Documents" -Exclude ("My*", ".ini")
如果您需要复制子目录,但排除了一些子目录,您可以构建一个不希望复制的目录列表,并在
Documents
文件夹中循环,然后对照列表检查每个项目。您可能需要进行试验,看看什么符合您的要求

使用Python

根据不同的需求,您的脚本显然会有所不同,但您可以使用此功能过滤掉特殊的文件夹和
.ini
文件

import os
from pathlib import Path
import shutil
from typing import Tuple
from shutil import copytree, ignore_patterns


def copy_documents_folder(source: Path, destination: Path, ext_to_ignore: Tuple):
    copytree(source, destination, ignore = ignore_patterns(*ext_to_ignore))

def main():

   try:

       user_profile = os.getenv("USERPROFILE")
       documents = Path(user_profile).joinpath("Documents")
       destination = Path("R:\\Sync\\Documents")

       copy_documents_folder(source=documents, destination=destination, 
       ext_to_ignore=("*.ini", "My *"))


   except (FileNotFoundError, shutil.Error) as error:
       print(error)


if __name__ == '__main__':
    main()

symlinks=true
不起作用。当我使用
is_symlink()
测试它时,它返回为false。这可能是shutil.copytree()的一个bug,但奇怪的是,为什么它试图复制
文档\我的音乐
文档\我的图片
,等等,即使请求没有在代码中给出,而且目录也不存在<批处理中的code>xcopy
和Powershell中的
Copy Item
都能正确地完成这项工作。使用
shutil.copytree()
复制普通文件夹是可行的,因此我不知道发生了什么。我将在有更多时间时发布一篇关于我经历的更详细的概述。
import os
from pathlib import Path
import shutil
from typing import Tuple
from shutil import copytree, ignore_patterns


def copy_documents_folder(source: Path, destination: Path, ext_to_ignore: Tuple):
    copytree(source, destination, ignore = ignore_patterns(*ext_to_ignore))

def main():

   try:

       user_profile = os.getenv("USERPROFILE")
       documents = Path(user_profile).joinpath("Documents")
       destination = Path("R:\\Sync\\Documents")

       copy_documents_folder(source=documents, destination=destination, 
       ext_to_ignore=("*.ini", "My *"))


   except (FileNotFoundError, shutil.Error) as error:
       print(error)


if __name__ == '__main__':
    main()