web-dev-qa-db-fra.com

IOError: [Errno 13] Autorisation refusée lors de la tentative d'ouverture d'un fichier caché en mode "w"

Je veux remplacer le contenu d'un fichier caché, j'ai donc essayé de l'ouvrir en mode w pour qu'il soit effacé/tronqué:

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

Mais cela a entraîné un retraçage:

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

Cependant, j'ai pu atteindre le résultat escompté avec r+ mode:

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

Q. Quelle est la différence entre le w et le r+ modes, tels que l'un a "autorisation refusée" mais l'autre fonctionne bien?

PDATE: Je suis sur win7 x64 en utilisant Python 2.6.6, et le fichier cible a son attribut caché défini. Lorsque j'ai essayé de désactiver l'attribut caché, w réussit. Mais lorsque je le rallume, il échoue à nouveau.

Q. Pourquoi le mode w échoue-t-il sur les fichiers cachés? Est-ce un comportement connu?

22
zedex

C'est juste comment l'API Win32 fonctionne. Sous le capot, la fonction open de Python appelle la fonction CreateFile , et si cela échoue, elle traduit le code d'erreur Windows en un Python IOError.

Le r+ le mode ouvert correspond à un dwAccessMode de GENERIC_READ|GENERIC_WRITE et un dwCreationDisposition de OPEN_EXISTING. Le mode ouvert w correspond à un dwAccessMode de GENERIC_WRITE et un dwCreationDisposition de CREATE_ALWAYS.

Si vous lisez attentivement les remarques dans la documentation CreateFile, cela dit ceci:

Si CREATE_ALWAYS et FILE_ATTRIBUTE_NORMAL sont spécifiés, CreateFile échoue et définit la dernière erreur sur ERROR_ACCESS_DENIED si le fichier existe et a le FILE_ATTRIBUTE_HIDDEN ou FILE_ATTRIBUTE_SYSTEM attribut. Pour éviter l'erreur, spécifiez les mêmes attributs que le fichier existant.

Donc, si vous appelez CreateFile directement à partir du code C, la solution serait d'ajouter FILE_ATTRIBUTE_HIDDEN au paramètre dwFlagsAndAttributes (au lieu de simplement FILE_ATTRIBUTE_NORMAL). Cependant, comme il n'y a pas d'option dans l'API Python pour lui dire de passer dans cet indicateur, vous devrez simplement le contourner en utilisant un mode ouvert différent ou en rendant le fichier non caché.

30
Adam Rosenfield

Voici les différences détaillées: -

`` r '' Ouvrir le fichier texte pour la lecture. Le flux est positionné au début du fichier.

`` r + '' Ouvert pour la lecture et l'écriture. Le flux est positionné au début du fichier.

`` w '' Tronquer le fichier à une longueur nulle ou créer un fichier texte pour l'écriture. Le flux est positionné au début du fichier.

`` w + '' Ouvert pour la lecture et l'écriture. Le fichier est créé s'il n'existe pas, sinon il est tronqué. Le flux est positionné au début du fichier.

`` a '' Ouvert pour l'écriture. Le fichier est créé s'il n'existe pas. Le flux est positionné à la fin du fichier. Les écritures ultérieures dans le fichier se termineront toujours à la fin du fichier alors en cours, indépendamment de toute fseek (3) intermédiaire ou similaire.

`` a + '' Ouvert pour la lecture et l'écriture. Le fichier est créé s'il n'existe pas. Le flux est positionné à la fin du fichier. Les écritures ultérieures dans le fichier se termineront toujours à la fin du fichier alors en cours, quel que soit le fseek (3) intervenant ou similaire.

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

Sous Windows, "b" ajouté au mode ouvre le fichier en mode binaire, il existe donc également des modes comme "rb", "wb" et "r + b". Python sous Windows fait une distinction entre les fichiers texte et binaires; les caractères de fin de ligne dans les fichiers texte sont automatiquement légèrement modifiés lorsque les données sont lues ou écrites. Cette modification en arrière-plan de les données de fichier sont correctes pour les fichiers texte ASCII, mais cela corrompra les données binaires comme celles des fichiers JPEG ou EXE. Soyez très prudent lorsque vous lisez et écrivez de tels fichiers en mode binaire. Sous Unix, cela ne fait pas de mal d'ajouter un "b" au mode, vous pouvez donc l'utiliser indépendamment de la plate-forme pour tous les fichiers binaires.

Donc, si vous utilisez le mode w, vous essayez en fait de créer un fichier et vous n'avez peut-être pas les autorisations pour le faire. r+ est le choix approprié.

Si vous êtes dans une situation où vous ne savez pas encore où votre .picasi.ini existe ou non et votre utilisateur Windows dispose d'autorisations de création de fichiers dans ce répertoire et vous souhaitez ajouter de nouvelles informations au lieu de commencer au début du fichier (a.k.a "append"), puis a+ sera le choix approprié.

Cela n'a rien à voir avec le fait que votre fichier soit caché ou non.

4
Calvin Cheng