Pythonic way to check if a file exists? [duplicate]
Asked Answered
D

5

251

Which is the preferred way to check if a file exists and if not create it?

Dewberry answered 13/2, 2010 at 22:40 Comment(1)
Actual duplicate question: Safely create a file if and only if it does not exist with python. In Python 3.3+, use the 'x' flag when open()ing a file to avoid race conditions.Mamelon
L
321

To check if a path is an existing file:

os.path.isfile(path)

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

Londrina answered 13/2, 2010 at 22:42 Comment(4)
Of course, you can get into a race condition where the file doesn't exist when you check, but springs into existence before you can create it. Extremely unlikely, but possible.Lorgnon
This will return true if a directory exists by the given name, in which case a subsequent creation of the file will fail.Lorgnon
I think you are thinking of os.path.exists, which returns True if the path exists (i.e. is a file or a directory). As shown above, os.path.isfile returns True when the path is a regular file.Kutch
This answer is outdated. On Python 3.4+ use pathlib, like this: Path("path/to/file").is_file() if you want to check that it's a file and that it exists or Path("path/to/file").exists() if you only want to know that it exists (but might be a directory).Carbide
M
95

Instead of os.path.isfile, suggested by others, I suggest using os.path.exists, which checks for anything with that name, not just whether it is a regular file.

Thus:

if not os.path.exists(filename):
    file(filename, 'w').close()

Alternatively:

file(filename, 'w+').close()

The latter will create the file if it exists, but not otherwise. It will, however, fail if the file exists, but you don't have permission to write to it. That's why I prefer the first solution.

Marble answered 13/2, 2010 at 22:56 Comment(3)
For Python 3 need to replace file with open: if not os.path.exists(filename): open(filename, "w+").close()Wadley
Did you mean to say, "The latter will create the file if it does not exist."?Bergsonism
Note that file(filename, 'w+').close() will truncate file if it exists.Labaw
T
42

It seems to me that all other answers here (so far) fail to address the race-condition that occurs with their proposed solutions.

Any code where you first check for the files existence, and then, a few lines later in your program, you create it, runs the risk of the file being created while you weren't looking and causing you problems (or you causing the owner of "that other file" problems).

If you want to avoid this sort of thing, I would suggest something like the following (untested):

import os

def open_if_not_exists(filename):
    try:
        fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
    except OSError, e:
        if e.errno == 17:
            print e
            return None
        else:
            raise
    else:
        return os.fdopen(fd, 'w')

This should open your file for writing if it doesn't exist already, and return a file-object. If it does exists, it will print "Ooops" and return None (untested, and based solely on reading the python documentation, so might not be 100% correct).

Tish answered 13/2, 2010 at 23:49 Comment(4)
This does work, but fobj = os.fdopen(fd) should be fobj = os.fdopen(ds, 'w') and after that os.close(fd).Sincerity
Actually the line needs to be fobj = os.fdopen(fd, 'w'). That's 'fd' not 'ds'Bicentennial
That exception catches everything and handles it all the same... it would be better if you explicitly named what should be getting caught there.Prevocalic
Should use except OSError as e.Simply
G
17

If (when the file doesn't exist) you want to create it as empty, the simplest approach is

with open(thepath, 'a'): pass

(in Python 2.6 or better; in 2.5, this requires an "import from the future" at the top of your module).

If, on the other hand, you want to leave the file alone if it exists, but put specific non-empty contents there otherwise, then more complicated approaches based on if os.path.isfile(thepath):/else statement blocks are probably more suitable.

Glennglenna answered 13/2, 2010 at 22:52 Comment(1)
open() is not an ideal solution compared to os.isfile. Open does unnecessary actions if you just want to check the existence of the file (though it is true, open is the best way to read and write files), and requires read privileges of the file to verify the existence of the file.Champ
G
-2

This was the best way for me. You can retrieve all existing files (be it symbolic links or normal):

os.path.lexists(path)

Return True if path refers to an existing path. Returns True for broken symbolic links. Equivalent to exists() on platforms lacking os.lstat().

New in version 2.4.
Gorge answered 2/5, 2013 at 17:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.