Python Shutil尝试复制不包含';不存在
我试图复制Windows用户配置文件下的Documents文件夹,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
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()