Check If a File Exists in Python: pathlib and os.path

Check if a file exists in Python with Path.is_file() and os.path.isfile(), avoid race conditions with try and open, and handle symlinks and patterns.

Python

In Python, we check whether a file exists with Path(path).is_file() from pathlib or os.path.isfile(path); both return True only for an existing regular file, while exists() also returns True for directories. When we are about to open the file anyway, catching FileNotFoundError is the safer pattern, because the file can disappear between the check and the open.

import os.path
from pathlib import Path

file = "notes.txt"
exists_os = os.path.isfile(file)        # True
exists_path = Path(file).is_file()      # True
folder_too = Path(".").exists()         # True, a directory also exists

We cover pathlib and os.path, files versus directories, relative paths, the race condition, symbolic links and permission checks. The examples run on Python 3.14 in a folder that contains notes.txt and a reports directory with april.csv and may.csv.

1. Using pathlib.Path to Check if a File Exists

The pathlib module represents paths as objects, and Path creates the right class for the operating system. Each method checks one kind of path.

MethodReturns True when the path is
is_file()An existing regular file, or a symlink to one
is_dir()An existing directory, or a symlink to one
exists()Any existing file or directory
is_symlink()A symbolic link, even a broken one
report_dir = Path("reports")
is_file = report_dir.is_file()          # False
is_dir = report_dir.is_dir()            # True
missing = Path("missing.txt").exists()  # False

We use is_file() when the code is about to read a file, because exists() also returns True for a directory with the same name.

1.1. Check if file exists on a relative path

A relative path is resolved against the current working directory, which is the folder the script was started from, not the folder of the script file. Building the path from __file__ makes it independent of where we run the script; __file__ exists only in script files, not in an interactive session or a notebook.

here = Path(__file__).parent              # the folder of this script
config = here / "notes.txt"
found = config.is_file()                  # True, wherever the script is started
cwd = Path.cwd()                          # the current working directory

2. Using os.path to Check if a File Exists

The os.path functions take path strings and give the same answers as the Path methods. They are common in older code and work well in small scripts.

f_ok = os.path.isfile("notes.txt")      # True
d_ok = os.path.isdir("reports")         # True
any_ok = os.path.exists("reports")      # True

3. Avoid the Race Condition: Try to Open the File

Between is_file() and open(), another process can delete or replace the file, so a check does not guarantee that the open succeeds. When the goal is to read the file, we try to open it and handle the exception, which Python developers call EAFP (easier to ask forgiveness than permission).

def read_text(path):
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        return None

content = read_text("missing.txt")      # None

To create a file only if it does not exist yet, mode “x” does the check and the creation in one atomic step and raises FileExistsError otherwise.

try:
    with open("lock.txt", "x", encoding="utf-8") as f:
        f.write("locked")
    created = True
except FileExistsError:
    created = False

4. Symbolic Links and Permissions

A broken symbolic link points to a missing target, so exists() and is_file() return False for it, while is_symlink() returns True. These checks also return False when the operating system denies access to the path, so a permission problem can look like a missing file; Path.stat() raises the real error instead.

can_read = os.access("notes.txt", os.R_OK)     # True
can_write = os.access("notes.txt", os.W_OK)    # True

The os.access() result can also change before we use the file, so it serves for messages to the user, not as a security check.

5. Finding Files by Pattern

To check whether any file matching a pattern exists, such as any CSV report, Path.glob() returns the matches, and any() turns them into a yes-or-no answer.

has_csv = any(Path("reports").glob("*.csv"))         # True
csv_names = sorted(p.name for p in Path("reports").glob("*.csv"))   # ['april.csv', 'may.csv']

6. File Existence FAQs

File checks that work on one machine and fail on another mostly have one of these causes.

6.1. Why does is_file() return False for a file we can see?

The script runs in a different working directory than expected, or the path has a typo or a different case on Linux. Printing Path(path).resolve() shows the absolute path Python checks.

6.2. How do we check if a directory is empty?

We check whether it has any entry, not any(Path(“reports”).iterdir()), which stops at the first entry instead of listing the whole folder.

6.3. Should we use pathlib or os.path?

Both work. pathlib is the modern choice, because paths combine with / and the same object offers reading, writing and checking methods.

7. Conclusion

To check for a file, Path.is_file() or os.path.isfile() is the right call, and exists() also accepts directories. When the code opens the file anyway, catching FileNotFoundError avoids the race condition, and mode “x” creates a file only if it is missing.

8. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.