关于文件io:制作目录时出现Python“FileExists”错误

Python “FileExists” error when making directory

我在集群系统上有几个并行运行的线程。 每个python线程输出到目录mydir。 每个脚本在输出检查之前是否存在mydir,如果不存在则创建它:

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

但这会产生错误:

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

我怀疑这可能是由于竞争条件,一个工作在另一个工作之前创建了dir。 这可能吗? 如果是这样,如何避免这种错误?

我不确定这是一个竞争条件,所以想知道Python中的其他问题是否会导致这个奇怪的错误。


从Python >=3.2开始,os.makedirs()可以采用第三个可选参数exist_ok

1
os.makedirs(mydir, exist_ok=True)


任何时候代码都可以在您检查某些内容和执行操作之间执行,您将遇到竞争条件。避免这种情况的一种方法(以及Python中的常用方法)是尝试然后处理异常

1
2
3
4
5
6
7
8
9
10
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


捕获异常,如果errno为17,则忽略它。如果isdirmakedirs调用之间存在竞争条件,那么这是唯一可以做的事情。

但是,也可能存在具有相同名称的文件 - 在这种情况下,os.path.exists将返回Trueos.path.isdir将返回false。


我有类似的问题,这就是我做的

1
2
3
4
5
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()检查路径来完成,并在那里我们传递了相应的目录名称。