2012-11-04 6 views
21

Ich möchte den Inhalt einer versteckten Datei ersetzen, also habe ich versucht, es in w Modus zu öffnen, so würde es gelöscht/abgeschnitten werden:IOError: [Errno 13] Berechtigung verweigert, wenn versteckte Datei im Modus "w" geöffnet werden soll

>>> 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') 

Aber dies führte zu einer Zurückverfolgungs:

IOError: [Errno 13] Permission denied: '.picasa.ini' 

Allerdings konnte ich das gewünschte Ergebnis mit r+ Modus erreichen:

>>> ini_handle = open(ini_path, 'r+') 
>>> ini_handle.truncate() 
>>> ini_handle.write(ini_new) 
>>> ini_handle.close() 

Q. Was ist der Unterschied zwischen den w und r+ Modi, so dass man "Berechtigung verweigert" aber die andere funktioniert gut?

UPDATE: Ich bin auf Win7 x64 mit Python 2.6.6, und die Zieldatei hat sein verstecktes Attribut festgelegt. Als ich versuchte, das versteckte Attribut auszuschalten, ist der w Modus erfolgreich. Aber wenn ich es wieder einschalte, schlägt es wieder fehl.

Q. Warum schlägt der Modus w bei versteckten Dateien fehl? Ist das bekannte Verhalten?

Antwort

27

So funktioniert die Win32-API. Unter der Haube ruft Pythons open Funktion die CreateFile Funktion auf, und wenn das fehlschlägt, übersetzt es den Windows-Fehlercode in einen Python IOError.

Der r+ offene Modus entspricht eine dwAccessMode von GENERIC_READ|GENERIC_WRITE und ein dwCreationDisposition von OPEN_EXISTING. Der offene Modus w entspricht einem dwAccessMode von GENERIC_WRITE und einem dwCreationDisposition von CREATE_ALWAYS.

Wenn Sie sorgfältig die Hinweise in der CreateFile Dokumentation lesen, heißt es dazu:

If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute. To avoid the error, specify the same attributes as the existing file.

Also, wenn Sie CreateFile direkt von C-Code aufrufen, wäre die Lösung in FILE_ATTRIBUTE_HIDDEN zum dwFlagsAndAttributes Parameter hinzuzufügen sein (statt nur FILE_ATTRIBUTE_NORMAL). Da es in der Python-API jedoch keine Option gibt, die besagt, dass sie dieses Flag übergeben soll, müssen Sie sie nur umgehen, indem Sie entweder einen anderen offenen Modus verwenden oder die Datei nicht verborgen machen.

+0

+1 für die Verknüpfung von Win32-API-Dokumenten. Ihre Erklärung ist genau das, wonach ich gesucht habe. Ich selbst bin nur bis zur [Implementierung] (http://hg.python.org/cpython/file/c6880edaf6f3/Objects/fileobject.c#l318) von Pythons 'open'-Funktion gekommen. – zedex

+0

@MrGamgee: Ja, Python ruft die Funktion '_wfopen' auf, die Teil der Microsoft C Runtime Library (CRT) ist. Wenn Sie Visual Studio installiert haben, können Sie die CRT-Quelle anzeigen, normalerweise in einem Verzeichnis wie 'C: \ Programme (x86) \ Microsoft Visual Studio 10.0 \ VC \ crt \ src'. Die Implementierung von '_wfopen' ruft schließlich' CreateFile' auf (nach einigen Zwischenfunktionsaufrufen). –

3

Hier sind die detaillierten Unterschiede: -

``r'' Open text file for reading. The stream is positioned at the beginning of the file.

``r+'' Open for reading and writing. The stream is positioned at the beginning of the file.

``w'' Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.

``w+'' Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.

``a'' Open for writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.

``a+'' Open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subse- quent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.

Von Python-Dokumentation - http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-

On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files. On Unix, it doesn’t hurt to append a 'b' to the mode, so you can use it platform-independently for all binary files.

Also, wenn Sie w-Modus verwenden, versuchen Sie tatsächlich eine Datei zu erstellen, und Sie dürfen nicht haben die Berechtigungen, es zu tun. r+ ist die richtige Wahl.

Wenn Sie in einer Situation sind, in der Sie noch nicht wissen, wo Ihre .picasi.ini existiert oder nicht und Ihr Windows-Benutzer Dateierstellungsberechtigungen in diesem Verzeichnis hat und Sie neue Informationen anhängen möchten, anstatt am Anfang der Datei zu beginnen (aka "append"), dann a+ wird die richtige Wahl sein.

Es hat nichts damit zu tun, ob Ihre Datei versteckt ist oder nicht.

+0

-1 zum Kopieren und Einfügen von Python-Dokumenten und nicht zum Lesen der Frage. Ich habe 'r +' Modus verwendet, der das Aktualisieren ermöglicht, dh sowohl Lesen als auch Schreiben. – zedex

+0

noch Bearbeitung der Antwort ... –

+0

Sie sagen "' w' Truncate Datei auf Null Länge oder erstellen Sie eine Textdatei zum Schreiben ". Aber dann sagst du später "Wenn du den' w' Modus verwendest, versuchst du tatsächlich eine Datei zu erstellen "Was ist das? – zedex

Verwandte Themen