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

Ошибка 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 вызвать эту нечетную ошибку.

4b9b3361

Ответ 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(), и там мы передали соответствующее имя каталога.