我试图复制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
试图复制这些特殊文件夹。如果我尝试在用户配置文件下复制常规文件夹,则可以使用。
答案 0 :(得分:0)
我不太了解Windows系统,但是您可以尝试致电
shutil.copytree(documents, destination, symlinks=True)
如果这些“特殊文件夹”是符号链接(或Windows的等效符号链接)。
答案 1 :(得分:0)
要了解为什么copytree()
在尝试复制Documents
时尝试复制special folders,我们必须首先查看隐藏的文件。
使用cmd.exe:
如果我们打开cmd.exe
并将目录更改为Documents
,则可以运行dir /A:H /B
来查看所有文件夹(包括隐藏的文件夹)。
C:\Users\ConsoleGeek\Documents>dir /A:H /B
desktop.ini
My Music
My Pictures
My Videos
使用Powershell :
如果我们打开powershell.exe
并键入Get-ChildItem -Force -File -Path .\Documents\
,它将列出Documents
文件夹中的所有项目。
注意:它不显示特殊文件夹。
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
使用文件资源管理器:
如果我选择了显示隐藏文件的选项,则Documents
文件夹仍然为空。
递归复制:
使用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 File(s) copied
具有误导性,因为当启用“显示隐藏的文件”时,您可以验证没有任何内容被复制。
使用Powershell :
将Copy-Item
cmdlet与-Recurse
开关一起使用,会出现访问拒绝错误,类似于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()