2012-11-04 22 views
21

Desidero sostituire il contenuto di un file nascosto, quindi ho tentato di aprirlo nella modalità w in modo da essere cancellato/troncato:IOError: [Errno 13] Autorizzazione negata quando si tenta di aprire il file nascosto in modalità "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') 

Ma questo ha comportato una traceback:

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

Tuttavia, sono stato in grado di ottenere il risultato desiderato con r+ modalità:

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

Q. Qual è la differenza tra le modalità w e r+, in modo tale che un utente ha il "permesso negato", ma l'altro funziona correttamente?

UPDATE: Sono su win7 x64 utilizzando Python 2.6.6 e il file di destinazione ha il set di attributi nascosti. Quando ho provato a disattivare l'attributo nascosto, la modalità w ha esito positivo. Ma quando lo riaccendo, fallisce di nuovo.

Q. Perché la modalità w non funziona sui file nascosti? È questo comportamento noto?

risposta

27

È proprio come funziona l'API Win32. Sotto il cofano, la funzione open di Python chiama la funzione CreateFile e, se fallisce, traduce il codice di errore di Windows in un Python IOError.

La modalità di apertura r+ corrisponde ad un dwAccessMode di GENERIC_READ|GENERIC_WRITE e un dwCreationDisposition di OPEN_EXISTING. La modalità aperta w corrisponde adi GENERIC_WRITE e a dwCreationDisposition di CREATE_ALWAYS.

Se leggete con attenzione le osservazioni nella documentazione CreateFile, si dice questo:

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.

Così se stessi chiamando CreateFile direttamente dal codice C, la soluzione sarebbe quella di aggiungere nel FILE_ATTRIBUTE_HIDDEN al parametro dwFlagsAndAttributes (invece di solo FILE_ATTRIBUTE_NORMAL). Tuttavia, poiché non c'è alcuna opzione nell'API Python per dirgli di passare in quella bandiera, dovrai solo aggirarla usando una modalità aperta diversa o rendendo il file non nascosto.

+0

+1 per il collegamento di documenti API Win32. La tua spiegazione è esattamente ciò che stavo cercando. Da solo, ho raggiunto solo la [implementazione] (http://hg.python.org/cpython/file/c6880edaf6f3/Objects/fileobject.c#l318) della funzione 'open' di Python. – zedex

+0

@MrGamgee: Sì, Python chiama la funzione '_wfopen', che fa parte della libreria di runtime Microsoft C (CRT). Se hai installato Visual Studio, puoi guardare l'origine CRT, in genere in "C: \ Programmi (x86) \ Microsoft Visual Studio 10.0 \ VC \ crt \ src'. L'implementazione di '_wfopen' alla fine chiama' CreateFile' (dopo alcune chiamate di funzioni intermedie). –

3

Ecco in dettaglio le differenze: -

``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.

dalla documentazione di pitone - 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.

Quindi, se si utilizza la modalità w, in realtà si sta tentando di creare un file e non si può avere i permessi per farlo r+ è la scelta appropriata.

Se ci si trova in una situazione in cui non si sa ancora dove si trova .picasi.ini e l'utente di Windows dispone di autorizzazioni per la creazione di file in tale directory e si desidera aggiungere nuove informazioni anziché iniziare all'inizio del file (alias "append"), quindi a+ sarà la scelta appropriata.

Non ha nulla a che fare se il tuo file è nascosto o meno.

+0

-1 per copiare e incollare da documenti Python e non leggere la domanda. Ho usato la modalità 'r +' che consente l'aggiornamento, cioè sia la lettura che la scrittura. – zedex

+0

modifica ancora la risposta ... –

+0

Si dice "' w' Tronca il file a lunghezza zero o crea file di testo per la scrittura ". Ma poi dici più tardi "se stai usando la modalità' w', stai effettivamente cercando di creare un file "Che cos'è? – zedex

Problemi correlati