我想replace一个隐藏文件的内容,所以我试图以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')
但是这导致了一个回溯:
IOError: [Errno 13] Permission denied: '.picasa.ini'
不过,我能用r+
模式达到预期的效果:
>>> ini_handle = open(ini_path, 'r+') >>> ini_handle.truncate() >>> ini_handle.write(ini_new) >>> ini_handle.close()
问: w
和r+
模式之间有什么区别,这样一个人有“权限被拒绝”,但另一个工作正常吗?
更新:我使用Python 2.6.6在win7 x64上,并且目标文件有其隐藏的属性集。 当我尝试closures隐藏属性时, w
模式成功。 但是当我把它重新打开,它再次失败。
问:为什么w
模式在隐藏文件上失败? 这是已知的行为?
这只是Win32 API的工作原理。 在底层,Python的open
函数调用CreateFile
函数,如果失败,它将Windows错误代码转换为Python IOError
。
r+
打开模式对应于GENERIC_READ|GENERIC_WRITE
的dwCreationDisposition
和OPEN_EXISTING
的dwCreationDisposition
。 w
打开模式对应于GENERIC_WRITE
的dwCreationDisposition
和CREATE_ALWAYS
的dwCreationDisposition
。
如果仔细阅读CreateFile
文档中的注释,它会这样说:
如果指定了
CREATE_ALWAYS
和FILE_ATTRIBUTE_NORMAL
,则CreateFile
失败并将最后一个错误设置为ERROR_ACCESS_DENIED
如果该文件存在且具有FILE_ATTRIBUTE_HIDDEN
或FILE_ATTRIBUTE_SYSTEM
属性。 为避免错误,请指定与现有文件相同的属性。
因此,如果您直接从C代码调用CreateFile
,则解决方案是将FILE_ATTRIBUTE_HIDDEN
添加到dwFlagsAndAttributes
参数(而不是仅FILE_ATTRIBUTE_NORMAL
)中。 但是,由于在Python API中没有选项可以让它通过该标志,所以只需要使用不同的开放模式或使文件不隐藏即可解决此问题。
以下是详细的区别:
“r”打开文本文件进行阅读。 流位于文件的开头。
“r +”开放阅读和写作。 流位于文件的开头。
“w''将文件截断为零,或者创建文本文件进行写入。 流位于文件的开头。
“w +”开放阅读和写作。 如果该文件不存在,则会创建该文件,否则会被截断。 流位于文件的开头。
“a''开放写作。 如果该文件不存在,则会创建该文件。 该流位于文件的末尾。 随后对文件的写操作将始终在文件的当前结束处结束,而不管任何介入fseek(3)或类似的操作。
“a +”开放阅读和写作。 如果该文件不存在,则会创建该文件。 该流位于文件的末尾。 对文件的后续写入将始终在文件的当前结束处结束,而不管任何介入的fseek(3)或类似文件。
从python文档 – http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-
在Windows上,附加到模式的“b”以二进制模式打开文件,所以也有像“rb”,“wb”和“r + b”这样的模式。 Windows上的Python区分文本和二进制文件; 读取或写入数据时,文本文件中的行尾字符会自动稍微改变。 这种对文件数据的后台修改对于ASCII文本文件来说是很好的,但是它会破坏像JPEG或者EXE文件那样的二进制数据。 读取和写入这些文件时要非常小心地使用二进制模式。 在Unix上,在模式中附加一个'b'并不会造成什么影响,所以你可以在所有的二进制文件中使用它。
所以,如果你使用的是w
模式,你实际上正在创建一个文件,而你可能没有权限去做。 r+
是合适的选择。
如果您的情况下,您还不知道.picasi.ini
存在与否,并且您的Windows用户在该目录中具有文件创建权限,并且您希望追加新的信息,而不是从文件的开始处开始(又名“append”),那么a+
就是合适的选择。
它与你的文件是否隐藏无关。