Atomically creating a file if it doesn't exist in Python
You can use os.open with os.O_CREAT | os.O_EXCL
flags which will fail if the file exists, they are according to the docs available on Unix and Windows but I am not sure if atomic file creation exists on windows or not:
os.open("filename", os.O_CREAT | os.O_EXCL)
From the linux open man page:
O_EXCL If O_CREAT and O_EXCL are set, open() shall fail if the file exists. The check for the existence of the file and the creation of the file if it does not exist shall be atomic with respect to other threads executing open() naming the same filename in the same directory with O_EXCL and O_CREAT set. If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not set, the result is undefined.
Not sure what you want to do if the file exists but you just need to catch a FileExistsError
when the file does already exist:
import os
def try_make_file(filename):
try:
os.open(filename, os.O_CREAT | os.O_EXCL)
return True
except FileExistsError:
return False
If you have Python 3.3 or better, you could use the 'x' mode with open()
:
'x' open for exclusive creation, failing if the file already exists
def tryMakeFile(filename):
try:
with open(filename, "x") as _:
return False
except FileExistsError:
return True
There's another variation of this, using pathlib.Path
:
from pathlib import Path
def try_make_file(filename):
try:
Path(filename).touch(exist_ok=False)
return True
except FileExistsError:
return False
It is not explicitly documented, but in the source code we can see that this implies the os.O_EXCL
flag:
if not exist_ok:
flags |= os.O_EXCL
See the function definition in the pathlib source code.
As such this carries the same properties as the other solutions (namely that it is unclear if this works on Windows).