在Windows上打开一个目录:'权限被拒绝'

4

我试图为一个目录获取文件描述符,但是在目录上调用os.open总是会导致"权限被拒绝"的错误。 我不认为这是一个权限问题,因为它发生在所有目录上,而在文件上没有问题(请参见下面的REPL会话)。以管理员身份运行也没有任何区别。

Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.mkdir('mydir')
>>> os.access('mydir', os.F_OK)
True
>>> os.access('mydir', os.R_OK)
True
>>> os.access('.', os.R_OK)
True
>>> os.access('.', os.F_OK)
True
>>> os.open('myfile', os.O_RDWR)
3
>>> os.open('mydir', os.O_RDONLY)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> os.open('mydir', os.O_RDWR)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> open('mydir')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 13] Permission denied: 'mydir'

在 Linux 上,它按预期运行:
>>> os.open('mydir', os.O_RDONLY)
3

文档没有说明不能在任何平台上获取目录的文件描述符。这是期望的行为吗?在Windows上无法获取目录的文件描述符吗?

如果可能的话,您会如何处理这些文件描述符?请查看http://stackoverflow.com/questions/16574511/open-a-windows-file-directory-for-reading-writing-in-c。 - manuell
你无法在Python内部提升权限。因此,为了解决这个问题,你需要以管理员或提升的权限运行Python,以打开你的文件。 - thecreator232
如果您使用“以管理员身份运行”打开命令提示符,然后尝试相同的操作会发生什么? - Tom
@thecreator232,Tom,我认为权限没问题(你可以看到目录甚至是由Python在repl中创建的)。以管理员身份运行也没有任何区别。我已经更新了问题以澄清。 - gwohpq9
2个回答

4

编辑:

这不是权限问题,Python 2永远不会起作用。当使用os.open()(代码:https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554)时,Python 2使用Win 32 API调用_wopen。根据文档,打开目录时会抛出一个错误:

EACCES 尝试以只读方式打开文件进行写入,文件的共享模式不允许指定的操作,或给定路径是目录。

所以:

文档没有表明您不能也没有任何平台差异。这是预期行为吗?

这是预期的行为。在这种情况下,我认为不需要在Python文档中澄清此细节。

在Windows上无法获取目录的文件描述符吗?

在Python 2中,您可以使用ctypes模块自己调用任意Win 32 API方法。 Python 3使用CreateFile而不是_wopen,这是一种更现代的API调用,它可能使您能够做到您想要的事情,如下所示。

旧答案:

这个问题最重要的资源是CreateFile Win 32 API函数的文档,文档在此处记录:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

您可能需要阅读其中相关部分,例如

要使用CreateFile打开目录,请将FILE_FLAG_BACKUP_SEMANTICS标志作为dwFlagsAndAttributes的一部分指定。

此外,文档下面有一条评论,说

为了打开一个目录句柄,即使您没有请求任何访问权限,似乎也需要SYNCHRONIZE访问权限。(注意:如果您拥有备份/恢复特权,则不适用。)

Python 3在多个位置使用此功能,您可能需要自己搜索

https://github.com/python/cpython/search?q=CreateFile&type=Code

您可以通过git克隆并使用grep -HR "CreateFile(" .来执行此操作。在Python 3中,_winapi.c模块最有可能在Windows上执行os.open()时被使用。

在Python 2中,在https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554中调用了_wopen,但我不确定这是定义的位置。当您按照此路径进行时,您将找到实际的实现。然后,您可以看到Python如何调用该函数--结合文档,这很可能会解释您的观察结果。


1
谢谢。我担心不得不直接使用win api。虽然你关于Python 3的说法,我认为是不正确的。我在Python 3中也遇到了同样的错误。 - gwohpq9
1
Python 3 中相同的错误 - Gerardo Buenrostro González
令人难以置信的是,近7年过去了他们仍然没有修复这个问题!特别是因为所有的指示,甚至在docs.python上都告诉你要使用:dir_fd = os.open('somedir', os.O_RDONLY); def opener(path, flags): return os.open(path, flags, dir_fd=dir_fd) - not2qubit

0

听起来你在Windows上没有正确的权限(也许在Linux上有)。这是来自http://windows.microsoft.com/zh-cn/windows/what-are-permissions#1TC=windows-7,它告诉你如何查找文件或目录上的权限。

要检查Windows中文件或文件夹的权限:

右键单击文件或文件夹,然后单击“属性”。

单击“安全”选项卡。

单击“组或用户名”下的用户或组。

所选用户或组的权限将显示在属性对话框的下部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接