Atomically creating a file if it doesn't exist in Python

前端 未结 3 501
死守一世寂寞
死守一世寂寞 2020-12-11 04:57

I am looking for an atomic version of the following:

import os

def tryMakeFile(filename):
    try:
        with open(         


        
相关标签:
3条回答
  • 2020-12-11 05:25

    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
    
    0 讨论(0)
  • 2020-12-11 05:31

    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
    
    0 讨论(0)
  • 2020-12-11 05:34

    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).

    0 讨论(0)
提交回复
热议问题