Я пытаюсь обработать JSON-декодирование путем резервного копирования искаженного файла в случае сбоя декодирования, но я испытываю странное поведение, которого я не ожидал от метода os.path.join
.
Следующий код завершается с ошибкой: PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'file.txt' -> 'file.txt\\.bak'
file_path = "file.txt"
try:
with open(file_path, 'r') as f:
json.load(f)
except json.JSONDecodeError as e:
os.rename(file_path, os.path.join(file_path, '.bak'))
Если я изменю аргумент следующим образом: os.rename(file_path, file_path + '.bak')
Код выполняется, как и ожидалось, без ошибки разрешения. Похоже, что метод os.path.join
фактически обращается к файлу, а не является строгой строковой операцией. Это ожидаемое поведение?
2 ответа
os.path.join(file_path, '.bak'))
на самом деле даст вам file.txt\\.bak
, как вы видите в коде ошибки, но file_path + '.bak'
даст вам правильное имя файла file.txt.bak
os.path.join добавляет разделитель между его аргументами, следовательно, он заканчивает тем, что добавил этот разделитель и в вашем случае
Например, в MacOS вы можете увидеть, что он добавляет разделитель между каждым из своих аргументов. os.path.join более полезен для добавления имен каталогов, полного имени файла с путями к каталогам.
In [4]: import os
In [5]: os.path.join('filename','.bak')
Out[5]: 'filename/.bak'
In [6]: os.path.join('folder1', 'folder2')
Out[6]: 'folder1/folder2'
Ошибка возникает из-за того, что ОС Windows пытается создать файл .bak
в папке с именем file.txt
, что невозможно, поскольку файл file.txt представляет собой обычный файл, а не каталог, что является правильным.
Использование file_path+'.bak
правильно создает file.path.bak
в нужной папке, поэтому вы не увидите там ошибки!
Сообщение об ошибке - это ключ. Как обычно в Windows причина ( потому что он используется другим процессом ) неверна, но имена ( 'file.txt' -> 'file.txt \ .bak' em>) верны.
Присоединение не является конкатенацией строк, но предполагает, что все члены пути, кроме последнего, представляют папки. Итак, здесь вы пытаетесь создать файл .bak
в папке с именем file.txt
. Это невозможно, потому что file.txt
- простой файл, а не каталог.
С другой стороны, когда вы используете os.rename(file_path, file_path + '.bak')
, вы переименовываете file.txt
в file.txt.bak
в той же папке, что разрешено базовой файловой системой, поэтому ошибка отсутствует.
Таким образом, поведение соответствует ожидаемому, за исключением начала сообщения об ошибке.
Поскольку я не являюсь ядром Microsoft Developper, следующее предположение является диким. Количество ошибок, указанных системой, ограничено. Функция переименования C получила 2 строки и передала их системному вызову для переименования. Как и ожидалось, файловая система вызвала ошибку, но так как она не была ни физической, ни полной ошибкой файловой системы, она просто выбрала причину отказано в разрешении . Что на самом деле не так, потому что нельзя создавать папки в виде простого файла. Но сообщение об этой ошибке, к сожалению, , потому что оно используется другим процессом , что здесь глупо
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.