IOError:[Errno 13]尝试以"w"模式打开隐藏文件时权限被拒绝

zed*_*dex 22 python windows file-io winapi hidden-files

我想替换隐藏文件的内容,所以我试图在w模式下打开它,因此它将被删除/截断:

>>> import os
>>> ini_path = '.picasa.ini'
>>> os.path.exists(ini_path)
True
>>> os.access(ini_path, os.W_OK)
True
>>> ini_handle = open(ini_path, 'w')
Run Code Online (Sandbox Code Playgroud)

但这导致了追溯:

IOError: [Errno 13] Permission denied: '.picasa.ini'
Run Code Online (Sandbox Code Playgroud)

但是,我能够通过r+模式实现预期的结果:

>>> ini_handle = open(ini_path, 'r+')
>>> ini_handle.truncate()
>>> ini_handle.write(ini_new)
>>> ini_handle.close()
Run Code Online (Sandbox Code Playgroud)

问:wr+模式之间的区别是什么,一个人有"权限被拒绝"但另一个工作正常?

更新:我使用Python 2.6.6在win7 x64上,目标文件有隐藏的属性集.当我尝试关闭隐藏属性时,w模式成功.但当我重新开启时,它再次失败.

问:为什么w模式在隐藏文件上失败?这是已知行为吗?

Ada*_*eld 30

这就是Win32 API的工作原理.在幕后,Python的open函数正在调用CreateFile函数,如果失败,它会将Windows错误代码转换为Python IOError.

r+开放的模式对应于dwAccessModeGENERIC_READ|GENERIC_WRITEdwCreationDispositionOPEN_EXISTING.在w开放的模式对应于dwAccessModeGENERIC_WRITEdwCreationDispositionCREATE_ALWAYS.

如果您仔细阅读CreateFile文档中的备注,它会说:

如果CREATE_ALWAYSFILE_ATTRIBUTE_NORMAL指定,则CreateFile失败并将最后一个错误设置ERROR_ACCESS_DENIED为文件是否存在且具有FILE_ATTRIBUTE_HIDDENor FILE_ATTRIBUTE_SYSTEM属性.要避免该错误,请指定与现有文件相同的属性.

因此,如果您CreateFile直接从C代码调用,解决方案是添加FILE_ATTRIBUTE_HIDDENdwFlagsAndAttributes参数(而不是仅仅FILE_ATTRIBUTE_NORMAL).但是,由于Python API中没有选项告诉它传递该标志,因此您只需要使用不同的打开模式或使文件不隐藏来解决它.


Cal*_*eng 5

以下是详细差异:-

\n\n
\n

``r\'\' 打开文本文件进行读取。该流位于文件的开头。

\n\n

``r+\'\' 打开以进行读写。该流位于文件的开头。

\n\n

``w\'\' 将文件截断为零长度或创建用于写入的文本文件。\n 流位于文件的开头。

\n\n

``w+\'\' 打开以进行读写。如果文件不存在,则创建该文件,否则将其截断。该流位于文件的开头。

\n\n

``a\'\' 打开用于写入。如果文件不存在,则创建该文件。\n 流位于文件末尾。对该文件的后续写入将始终在文件的当前末尾结束,而不管任何中间的 fseek(3) 或类似内容。

\n\n

``a+\'\' 打开以进行读写。如果文件不存在,则创建该文件。该流位于文件末尾。对文件的后续写入将始终在当前文件末尾结束,无论是否有任何介入的 fseek(3) 或类似内容。

\n
\n\n

来自 python 文档 - http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-

\n\n
\n

在 Windows 上,附加到模式的“b”以二进制模式打开文件,因此还有“rb”、“wb”和“r+b”等模式。Windows 上的 Python 区分文本文件和二进制文件;当读取或写入数据时,文本文件中的行尾字符会自动稍微更改。这种对文件数据的幕后修改对于 ASCII 文本文件来说是没问题的,但它会损坏 JPEG 或 EXE 文件中的二进制数据。读取和写入此类文件时要非常小心地使用二进制模式。在 Unix 上,\xe2\x80\x99 向模式附加 \'b\' 不会有什么坏处,因此你可以独立于平台对所有二进制文件使用它。

\n
\n\n

因此,如果您使用w模式,您实际上是在尝试创建一个文件,并且您可能没有执行此操作的权限。r+是合适的选择。

\n\n

如果您还不知道您的文件.picasi.ini存在或不存在,并且您的 Windows 用户在该目录中具有文件创建权限,并且您想要附加新信息而不是从文件开头开始(也称为“附加”) ,那么a+就会是合适的选择。

\n\n

它与您的文件是否隐藏无关。

\n

  • “这与你的文件是否隐藏无关。” 请考虑以下事实: (1) 设置隐藏属性。(2)`w`模式失败。(3) 取消设置隐藏属性 (4) `w` 模式成功。这是可重复的。我刚刚检查了“ini”和“jpg”文件。 (3认同)