如果文件不存在于Python中,则自动创建该文件

2022-04-18 00:00:00 python atomic

问题描述

我正在寻找以下内容的原子版本:

import os

def tryMakeFile(filename):
    try:
        with open(filename) as _:
            return False
    except FileNotFoundError:
        with open(filename, mode='a') as _:
            return True

(请不要在这里评论文体问题-我知道这段代码在很多方面都不好,但它足以说明我的问题。)

换句话说,我正在寻找一种方法来检查文件是否存在,如果不存在,则在Python语言中以一种我知道发生了什么的方式创建它。但以这样一种方式完成,即多个进程之间不存在竞争条件(在我给定的示例代码中,如果第二个进程运行,而第一个进程在第一个和第二个打开的调用之间挂起,则两个进程都可能认为它们创建了文件)。

或者换一种说法,我正在寻找一个与Java的Files.createFile调用等同的Python。

编辑:请注意,当我说"Python"时,我指的是"可移植的Python"。说"使用这个库*(这个库只在Windows上可用,或者不能在Windows上使用,或者只能在蓝月亮之后的第二个星期二使用)"不是我想要的。我正在寻找一种明确的原子性的东西,它是标准库和/或内置的一部分,并且可以在公共平台上使用。


解决方案

您可以使用os.open和os.O_CREAT | os.O_EXCLflags,如果文件存在则会失败,它们是根据unix和windows上提供的文档,但我不确定Windows上是否存在原子文件创建:

os.open("filename", os.O_CREAT | os.O_EXCL)

来自Linuxopen man page:

O_EXCL 如果设置了O_CREAT和O_EXCL,如果文件存在,则Open()将失败。对于在设置了O_EXCL和O_CREAT的同一目录中执行Open()命名的其他线程,检查文件是否存在以及创建文件(如果不存在)应该是原子的。如果设置了O_EXCL和O_CREAT,并且路径命名为符号链接,则open()将失败,并将errno设置为[EEXIST],而不管符号链接的内容如何。如果已设置O_EXCL,但未设置O_CREAT,则结果未定义。

不确定文件存在时要做什么,但只需在文件已存在时捕获FileExistsError

import os

def try_make_file(filename):
    try:
        os.open(filename,  os.O_CREAT | os.O_EXCL)
        return True
    except FileExistsError:
        return False

相关文章