Ошибка Python "FileExists" при создании каталога
У меня есть несколько потоков, работающих параллельно с Python в кластерной системе. Каждый поток python выводится в каталог mydir
. Каждый script перед выдачей чеков, если mydir существует, а если не создает его:
if not os.path.isdir(mydir):
os.makedirs(mydir)
но это дает ошибку:
os.makedirs(self.log_dir)
File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name,mode)
OSError: [Errno 17] File exists
Я подозреваю, что это может быть связано с состоянием гонки, когда одна работа создает директорию, прежде чем другой доберется до нее. Это возможно? Если да, как можно избежать этой ошибки?
Я не уверен, что это состояние гонки, поэтому было интересно, могут ли другие проблемы в Python вызвать эту нечетную ошибку.
Ответы
Ответ 1
Любой временной код может выполняться между тем, когда вы что-то проверяете, и когда вы действуете на нем, у вас будет состояние гонки. Один из способов избежать этого (и обычный способ в Python) - просто попытаться обработать исключение
while True:
mydir = next_dir_name()
try:
os.makedirs(mydir)
break
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
# time.sleep might help here
pass
Если у вас много потоков, пытающихся создать предсказуемую серию каталогов, это все равно вызовет множество исключений, но вы попадете туда в конце. Лучше просто создать один поток, создающий dirs в этом случае
Ответ 2
Поймать исключение и, если errno равно 17, игнорировать его. Это единственное, что вы можете сделать, если есть условие гонки между вызовами isdir
и makedirs
.
Однако также возможно, что файл с тем же именем существует - в этом случае os.path.exists
будет возвращать True
, но os.path.isdir
возвращает false.
Ответ 3
Как и в Python >=3.2
, os.makedirs()
может принимать третий необязательный аргумент exist_ok
:
os.makedirs(mydir, exist_ok=True)
Ответ 4
У меня были подобные проблемы, и вот что я сделал
try:
if not os.path.exists(os.path.dirname(mydir)):
os.makedirs(os.path.dirname(mydir))
except OSError as err:
print(err)
Описание:
Просто проверяя, существует ли уже существующая директория, это сообщение об ошибке [Errno 17] Файл существует
потому что мы просто проверяем, существует или нет имя каталога , которое будет возвращать имя каталога передаваемого значения mydir, но не если оно уже существует или нет. То, что упускается, не проверяет, существует ли этот каталог, который можно сделать, проверив путь с помощью os.path.exists(), и там мы передали соответствующее имя каталога.