classes - python opp
IOError:[Errno 13] Permiso denegado al intentar abrir el archivo oculto en el modo "w" (2)
Quiero reemplazar el contenido de un archivo oculto, así que intenté abrirlo en modo w
para que se borre / trunque:
>>> 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'')
Pero esto dio como resultado un rastreo:
IOError: [Errno 13] Permission denied: ''.picasa.ini''
Sin embargo, pude lograr el resultado deseado con el modo r+
:
>>> ini_handle = open(ini_path, ''r+'')
>>> ini_handle.truncate()
>>> ini_handle.write(ini_new)
>>> ini_handle.close()
P. ¿Cuál es la diferencia entre los modos w
y r+
, de modo que uno tiene "permiso denegado" pero el otro funciona bien?
ACTUALIZACIÓN: estoy en win7 x64 usando Python 2.6.6, y el archivo de destino tiene su atributo oculto establecido. Cuando intenté apagar el atributo oculto, el modo w
tiene éxito. Pero cuando lo enciendo de nuevo, falla nuevamente.
P. ¿Por qué el modo w
falla en los archivos ocultos? ¿Es este comportamiento conocido?
Aquí están las diferencias detalladas:
`` r '''' Abrir archivo de texto para leer. La secuencia se coloca al principio del archivo.
`` r + '''' Abierto para leer y escribir. La secuencia se coloca al principio del archivo.
`` w '''' Truncar archivo a longitud cero o crear archivo de texto para escribir. La secuencia se coloca al principio del archivo.
`` w + '''' Abierto para leer y escribir. El archivo se crea si no existe, de lo contrario se trunca. La secuencia se coloca al principio del archivo.
`` a '''' Abierto para escribir. El archivo se crea si no existe. La secuencia se coloca al final del archivo. Las escrituras subsiguientes en el archivo siempre terminarán en el final del archivo actual, independientemente de cualquier fseek intermedio (3) o similar.
`` a + '''' Abierto para leer y escribir. El archivo se crea si no existe. La secuencia se coloca al final del archivo. Las subsiguientes escrituras en el archivo siempre terminarán en el final del archivo actual, independientemente de cualquier fseek intermedio (3) o similar.
De la documentación de Python - http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-
En Windows, ''b'' agregado al modo abre el archivo en modo binario, por lo que también hay modos como ''rb'', ''wb'' y ''r + b''. Python en Windows hace una distinción entre archivos de texto y binarios; los caracteres de fin de línea en los archivos de texto se modifican automáticamente cuando se leen o escriben los datos. Esta modificación entre bastidores de los datos de archivos está bien para los archivos de texto ASCII, pero dañará los datos binarios de esa manera en los archivos JPEG o EXE. Tenga mucho cuidado de usar el modo binario al leer y escribir dichos archivos. En Unix, no está de más agregar una ''b'' al modo, por lo que puedes usarla independientemente de la plataforma para todos los archivos binarios.
Entonces, si está utilizando el modo w
, en realidad está intentando crear un archivo y es posible que no tenga los permisos para hacerlo. r+
es la elección adecuada.
Si se encuentra en una situación en la que aún no sabe dónde existe o no su .picasi.ini
y su usuario de Windows tiene permisos de creación de archivos en ese directorio y desea agregar información nueva en lugar de comenzar al principio del archivo (aka "append"), entonces a+
será la elección adecuada.
No tiene nada que ver con si su archivo está oculto o no.
Así es como funciona la API de Win32. Bajo el capó, la función open
de Python llama a la función CreateFile
, y si eso falla, traduce el código de error de Windows en un Python IOError
.
El modo r+
open corresponde a un dwAccessMode
de GENERIC_READ|GENERIC_WRITE
y una dwCreationDisposition
de dwCreationDisposition
. El modo w
open corresponde a un dwAccessMode
de GENERIC_WRITE
y a dwCreationDisposition
de CREATE_ALWAYS
.
Si lee cuidadosamente los comentarios en la documentación CreateFile
, dice esto:
Si se especifican
CREATE_ALWAYS
yFILE_ATTRIBUTE_NORMAL
,CreateFile
falla y establece el último error enERROR_ACCESS_DENIED
si el archivo existe y tiene el atributoFILE_ATTRIBUTE_HIDDEN
oFILE_ATTRIBUTE_SYSTEM
. Para evitar el error, especifique los mismos atributos que el archivo existente.
Por lo tanto, si llama a CreateFile
directamente desde el código C, la solución sería agregar FILE_ATTRIBUTE_HIDDEN
al parámetro dwFlagsAndAttributes
(en lugar de FILE_ATTRIBUTE_NORMAL
). Sin embargo, dado que no hay ninguna opción en la API de Python para indicarle que pase en ese indicador, tendrá que evitarlo utilizando un modo abierto diferente o haciendo que el archivo no se oculte.