Подтвердить что ты не робот

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 отключается в скрытых файлах? Это известное поведение?

4b9b3361

Ответ 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+ будет подходящим выбором.

Это не имеет никакого отношения к тому, скрыт ли ваш файл или нет.