我试图创建一个目录然后将其删除(出于测试目的,我将忽略,但如果需要可以提供详细信息)。
像这样:
>>> import os
>>> os.makedirs('C:\\ProgramData\\dir\\test')
>>> os.remove('C:\\ProgramData\\dir\\test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
PermissionError: [WinError 5] Access is denied: 'C:\\ProgramData\\dir\\test'
我总是拒绝访问,虽然我是以管理员身份运行解释器。我也没有问题手动删除目录。
答案 0 :(得分:3)
答案 1 :(得分:1)
使用os.rmdir
删除目录。在Windows上,这是通过调用WinAPI函数RemoveDirectory
来实现的。 os.remove
是通过调用DeleteFile
实现的,ERROR_ACCESS_DENIED
仅用于删除文件。如果filename参数是一个目录,则调用失败并将最后一个错误代码设置为NTSTATUS
code,Python 3将为此引发PermissionError
。
在这种情况下,访问被拒绝错误基于RtlNtStatusToDosError
STATUS_FILE_IS_A_DIRECTORY
,即division of labor (0xC00000BA) == 5
。通常,内核的状态代码比相应的WinAPI错误信息更丰富,但并非总是如此,并且始终不会从一个到另一个的简单映射,具体取决于内核之间的NtOpenFile
,系统进程,服务,环境子系统和应用程序。在这种情况下,我认为内核状态代码无疑比通用访问拒绝错误更具信息性。
在较低级别,尝试通过DeleteFile
删除目录时出现错误的原因是,它调用了系统服务NtSetInformationFile
,并在FILE_NON_DIRECTORY_FILE
中设置了OpenOptions
标记} {而RemoveDirectory
指定FILE_DIRECTORY_FILE
。随后,两个函数都会调用file streams来设置FileDispositionInformation
以删除文件或目录。
只是成为一个逆向者,让我们在NTFS文件系统上仅使用 file 操作来实现整个序列。
>>> import os, pathlib
>>> base = pathlib.Path(os.environ['ProgramData'])
创建&#39; dir&#39;目录:
>>> dirp = base / 'dir::$INDEX_ALLOCATION'
>>> open(str(dirp), 'w').close()
>>> os.path.isdir(str(dirp))
True
通过手动将流类型指定为$INDEX_ALLOCATION
,打开此文件&#39;实际上创建了一个NTFS目录。顺便提一下,您还可以将多个名为$DATA
的流添加到目录。请参阅{{3}}主题。
接下来创建&#39;测试&#39;子目录并调用os.remove
删除它:
>>> test = base / 'dir' / 'test::$INDEX_ALLOCATION'
>>> open(str(test), 'w').close()
>>> os.path.isdir(str(test))
True
>>> os.remove(str(test))
>>> os.path.exists(str(test))
False
你可能会对此感到惊讶。请记住,在这种情况下,文件名显式指定$INDEX_ALLOCATION
流。这取代了FILE_NON_DIRECTORY_FILE
标志。你得到了你所要求的。但不要依赖于此,因为这些流是NTFS的实现细节,它不是Windows上唯一使用的文件系统。