web-dev-qa-db-ja.com

Pythonディレクトリ作成時の「FileExists」エラー

クラスターシステムでPython=から複数のスレッドが並列に実行されています。各pythonスレッドはディレクトリmydirに出力します。各スクリプトは、前に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

1つのジョブがdirを作成してから、他のジョブがそれに到達するという競合状態が原因である可能性があります。これは可能ですか?もしそうなら、このエラーをどのように回避できますか?

私はそれが競合状態であるかどうかわからないので、Pythonの他の問題がこの奇妙なエラーを引き起こす可能性があるかどうか疑問に思っていました。

42
user248237

何かをチェックしてからアクションを実行するまでの間にコードが実行できるときはいつでも、競合状態になります。これを回避する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を作成するスレッドを1つだけ持つ方が良い

48
John La Rooy

Python _>=3.2_以降、os.makedirs()は3番目のオプションの引数_exist_ok_を取ることができます:

_os.makedirs(mydir, exist_ok=True)
_
60
Jahid

例外をキャッチし、errnoが17の場合は無視してください。 isdirmakedirsの呼び出しの間に競合状態がある場合に実行できるのは、これだけです。

ただし、同じ名前のfileが存在する可能性もあります。その場合、os.path.existsTrueを返しますが、os.path.isdirはfalseを返します。

16
ThiefMaster

私は同様の問題があり、ここに私がやったことがあります

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()でチェックすることで確認でき、そこにそれぞれのディレクトリ名を渡しました。

1

Dirまたはfile existエラーを無視するには、次のことを試してください。

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