web-dev-qa-db-fra.com

Python Erreur "FileExists" lors de la création du répertoire

J'ai plusieurs threads fonctionnant en parallèle depuis Python sur un système de cluster. Chaque thread python sort dans un répertoire mydir. Chaque script, avant la sortie vérifie si mydir existe et sinon le crée:

if not os.path.isdir(mydir):
    os.makedirs(mydir)

mais cela donne l'erreur:

os.makedirs(self.log_dir)                                             
  File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name,mode)
OSError: [Errno 17] File exists

Je soupçonne que cela pourrait être dû à une condition de concurrence, où un travail crée le dir avant que l'autre n'y arrive. Est-ce possible? Si oui, comment éviter cette erreur?

Je ne suis pas sûr que ce soit une condition de concurrence, alors je me demandais si d'autres problèmes dans Python peuvent provoquer cette étrange erreur.

42
user248237

Tout code temporel peut s'exécuter entre le moment où vous vérifiez quelque chose et le moment où vous agissez dessus, vous aurez une condition de concurrence. Une façon d'éviter cela (et la manière habituelle en Python) est d'essayer puis de gérer l'exception

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

Si vous avez beaucoup de threads essayant de créer une série prévisible de répertoires, cela soulèvera toujours de nombreuses exceptions, mais vous y arriverez à la fin. Mieux vaut avoir un seul thread créant les répertoires dans ce cas

48
John La Rooy

À partir de Python >=3.2, os.makedirs() peut prendre un troisième argument optionnel exist_ok:

os.makedirs(mydir, exist_ok=True)
60
Jahid

Attrapez l'exception et, si le numéro d'erreur est 17, ignorez-le. C'est la seule chose que vous pouvez faire s'il y a une condition de concurrence entre les appels isdir et makedirs.

Cependant, il pourrait également être possible qu'un fichier avec le même nom existe - dans ce cas os.path.exists renverrait True mais os.path.isdir renvoie faux.

16
ThiefMaster

J'ai eu des problèmes similaires et voici ce que j'ai fait

try:
   if not os.path.exists(os.path.dirname(mydir)):
       os.makedirs(os.path.dirname(mydir))
except OSError as err:
   print(err)

Description: Le simple fait de vérifier si le répertoire existe déjà génère ce message d'erreur [Errno 17] Le fichier existe car nous vérifions simplement si le nom de répertoire existe ou non qui renverra le nom de répertoire de la valeur mydir passée mais pas si elle existe déjà ou non. Ce qui manque, ce n'est pas de vérifier si ce répertoire existe déjà, ce qui peut être fait en vérifiant le chemin avec os.path.exists () et là nous avons passé le nom du répertoire respectif.

1
Tara Prasad Gurung

Pour ignorer l'erreur d'existence du répertoire ou du fichier, vous pouvez essayer ceci:

    except OSError, e:
        if e.errno != 17:
            print("Error:", e)
0
Ella