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+
, так что у вас есть "разрешение отклонено", но другое отлично работает?
UPDATE: Я нахожусь на win7 x64, используя Python 2.6.6, а целевой файл имеет свой скрытый набор атрибутов. Когда я попытался отключить скрытый атрибут, режим w
завершается успешно. Но когда я верну его, он снова не сработает.
Q. Почему режим w
отключается в скрытых файлах? Это известное поведение?
Ответы
Ответ 1
Как работает Win32 API. Под капотом функция Python open
вызывает функцию CreateFile
, и если это не удается, она преобразует код ошибки Windows в Python IOError
.
Режим open r+
соответствует a dwAccessMode
GENERIC_READ|GENERIC_WRITE
и a dwCreationDisposition
of OPEN_EXISTING
. Открытая мода w
соответствует a dwAccessMode
GENERIC_WRITE
и a dwCreationDisposition
of CREATE_ALWAYS
.
Если вы внимательно прочитали примечания в документации CreateFile
, это говорит следующее:
Если указаны CREATE_ALWAYS
и FILE_ATTRIBUTE_NORMAL
, CreateFile
не работает и устанавливает последнюю ошибку в ERROR_ACCESS_DENIED
, если файл существует и имеет атрибут FILE_ATTRIBUTE_HIDDEN
или FILE_ATTRIBUTE_SYSTEM
. Чтобы избежать ошибки, укажите те же атрибуты, что и существующий файл.
Итак, если вы вызывали CreateFile
непосредственно из C-кода, решение было бы добавить в FILE_ATTRIBUTE_HIDDEN
к параметру dwFlagsAndAttributes
(а не просто FILE_ATTRIBUTE_NORMAL
). Однако, поскольку в API-интерфейсе Python нет возможности пропустить это для того, чтобы передать этот флаг, вам просто придется обойти его, либо используя другой открытый режим, либо сделав файл не скрытым.
Ответ 2
Ниже приведены подробные различия: -
`` r '' Откройте текстовый файл для чтения. Поток расположен на начало файла.
`` r + '' Открыт для чтения и записи. Поток расположен в начало файла.
`` w '' Обрезать файл до нулевой длины или создать текстовый файл для записи. Поток расположен в начале файла.
`` w + '' Открыт для чтения и записи. Файл создается, если он не существует, в противном случае он усекается. Поток расположен в начало файла.
`` a '' Открыт для записи. Файл создается, если он не существует. поток расположен в конце файла. Последующие записи к файлу всегда будет конец в текущем конце файла, независимо от любого промежуточного fseek (3) или подобного.
`` a + '' Открыт для чтения и записи. Файл создается, если он не существовать. Поток расположен в конце файла. Последовавшие quent пишет в файл, всегда будет заканчиваться на текущем конец файла, независимо от любого промежуточного fseek (3) или подобного.
Из документации python - http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:-
В Windows, 'b', добавленный в режим, открывает файл в двоичном режиме, поэтому существуют также такие режимы, как "rb", "wb" и "r + b". Python в Windows делает различие между текстовыми и двоичными файлами; конец строки символы в текстовых файлах автоматически изменяются, когда данные читается или записывается. Эта за кадром модификация данных файла отлично подходит для текстовых файлов ASCII, но itll повреждает двоичные данные, подобные этому в файлах JPEG или EXE. Будьте очень осторожны при использовании двоичного режима при чтении и писать такие файлы. В Unix не помешает добавить "b" в режим, поэтому вы можете использовать его платформу-независимо для всех двоичных файлы.
Итак, если вы используете режим w
, вы на самом деле пытаетесь создать файл, и у вас могут не быть разрешения на его выполнение. r+
является подходящим выбором.
Если вы находитесь в ситуации, когда вы еще не знаете, где ваш .picasi.ini
существует или нет, и у вашего пользователя Windows есть разрешения на создание файлов в этом каталоге, и вы хотите добавить новую информацию вместо начала в начале файла (aka "append" ), тогда a+
будет подходящим выбором.
Это не имеет никакого отношения к тому, скрыт ли ваш файл или нет.