web-dev-qa-db-ja.com

IOError:[Errno 13]「w」モードで隠しファイルを開こうとすると許可が拒否されました

隠しファイルの内容を置き換えたいので、それを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()

Q。wモードとr+モードの違いは何ですか。一方は「許可が拒否されました」が、もう一方は正常に動作しますか。

PDATE: win7 x64でPython 2.6.6を使用しており、ターゲットファイルに隠し属性が設定されています。隠し属性をオフにしようとすると、wモードは成功しますが、再びオンにすると、再び失敗します。

Q。隠しファイルでwモードが失敗するのはなぜですか?これは既知の動作ですか?

22
zedex

Win32 APIの仕組みです。内部では、Pythonのopen関数は CreateFile 関数を呼び出しており、それが失敗した場合、WindowsエラーコードをPython IOError

r+オープンモードは、GENERIC_READ|GENERIC_WRITEdwAccessModeおよびOPEN_EXISTINGdwCreationDispositionに対応します。 wオープンモードは、GENERIC_WRITEdwAccessModeおよびCREATE_ALWAYSdwCreationDispositionに対応します。

CreateFileドキュメントの注意を注意深く読むと、次のように書かれています。

CREATE_ALWAYSおよびFILE_ATTRIBUTE_NORMALが指定されている場合、CreateFileは失敗し、ファイルが存在し、ERROR_ACCESS_DENIEDまたはFILE_ATTRIBUTE_HIDDEN属性を持つ場合、最後のエラーをFILE_ATTRIBUTE_SYSTEMに設定します。エラーを回避するには、既存のファイルと同じ属性を指定します。

したがって、CコードからCreateFileを直接呼び出している場合、解決策はFILE_ATTRIBUTE_HIDDENdwFlagsAndAttributesパラメーターに追加することです(単なるFILE_ATTRIBUTE_NORMALではなく)。ただし、Python APIにはそのフラグを渡すように指示するオプションがないため、別のオープンモードを使用するか、ファイルを非隠された。

30
Adam Rosenfield

詳細な違いは次のとおりです。

`` r ''テキストファイルを読み取り用に開きます。ストリームはファイルの先頭に配置されます。

`` r + ''読み取りおよび書き込み用に開きます。ストリームはファイルの先頭に配置されます。

`` w ''ファイルを長さゼロに切り捨てるか、書き込み用のテキストファイルを作成します。ストリームはファイルの先頭に配置されます。

`` w + ''読み取りおよび書き込み用に開きます。ファイルが存在しない場合は作成され、存在しない場合は切り捨てられます。ストリームはファイルの先頭に配置されます。

「a」書き込み用に開きます。ファイルが存在しない場合は作成されます。ストリームはファイルの末尾に配置されます。後続のファイルへの書き込みは、介在するfseek(3)などに関係なく、常に現在のファイルの終わりで終了します。

`` a + ''読み取りおよび書き込み用に開きます。ファイルが存在しない場合は作成されます。ストリームはファイルの末尾に配置されます。後続のファイルへの書き込みは、介在するfseek(3)などに関係なく、常に現在のファイルの終わりになります。

From python documentation- http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-

Windowsでは、モードに「b」を追加すると、ファイルがバイナリモードで開かれるため、「rb」、「wb」、「r + b」などのモードもあります。 Pythonは、テキストファイルとバイナリファイルを区別します。テキストファイルの行末文字は、データの読み取りまたは書き込み時に自動的にわずかに変更されます。 ASCIIテキストファイルのファイルデータは問題ありませんが、JPEGまたはEXEファイルのようなバイナリデータは破損します。このようなファイルの読み取りと書き込みを行うときは、バイナリモードを使用してください。モードに「b」を追加しても問題はないため、すべてのバイナリファイルに対してプラットフォームに依存せずに使用できます。

したがって、wモードを使用している場合、実際にはファイルを作成しようとしているため、そのためのアクセス許可がない可能性があります。 r+が適切な選択です。

.picasi.iniが存在するかどうかにかかわらず、Windowsユーザーはそのディレクトリにファイル作成権限を持ち、ファイルの先頭から開始する代わりに新しい情報を追加する(別名「追加」)後、a+が適切な選択です。

ファイルが隠されているかどうかとは関係ありません。

4
Calvin Cheng