How do I check whether a file exists without exceptions?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Checking whether a file exists sounds simple, but the correct answer depends on what happens next. In Python, you can check existence without exceptions by using pathlib or os.path, but for critical workflows you still need to think about race conditions and whether you actually care about a file, a directory, or any path at all.
The Simplest Existence Check
The modern Python answer is Path.exists().
This check returns True for both files and directories. If all you want to know is whether some path exists, this is fine.
The older os.path.exists version works too:
Check Specifically for a Regular File
Many bugs happen because the code asks "does this path exist" when the real question is "is this a file".
If directories should be rejected, is_file() is the better choice.
Normalize the Path Before Checking
Sometimes the check fails because the path is relative, includes ~, or is being resolved from an unexpected working directory. Expanding and normalizing the path makes debugging much easier.
That does not change whether the file exists, but it makes the program's behavior clearer when paths come from user input or configuration.
Why Check-Then-Use Can Still Be Unsafe
This is the subtle part: a file can disappear after you check it and before you open it. Another process might delete it, replace it, or change permissions in that small time window.
That means this pattern is not truly safe for critical operations:
For robust code, the safer pattern is often to perform the operation directly and handle the failure if it occurs.
That does use an exception, but it avoids the race condition.
Creating a File Only If It Does Not Exist
If the goal is to write a new file without overwriting an existing one, exclusive creation mode is better than a separate existence test.
This is atomic. It avoids the classic bug where two processes both check for existence, both see "missing," and both try to create the same file.
When a Plain Check Is Enough
A non-exception check is perfectly reasonable when:
- you are showing a user a hint in the UI,
- you are deciding whether to display an optional file,
- the result is informational rather than security- or correctness-critical,
- a race condition would not hurt anything important.
The mistake is using a plain existence check as if it guaranteed the next file operation will succeed.
Common Pitfalls
A common mistake is using exists() when the code really needs is_file(). A directory can exist too, and treating it like a file causes confusing failures later.
Another issue is forgetting that path checks are relative to the current working directory unless you normalize or resolve them. Many "missing file" bugs are actually "wrong directory" bugs.
Developers also often assume existence implies readability. A file may exist but still be blocked by permissions or locking.
Summary
- Use
Path.exists()oros.path.exists()for a simple non-exception existence check. - Use
Path.is_file()when directories should not count. - Normalize paths early so diagnostics are clear.
- For critical operations, prefer doing the file operation directly and handling failure.
- Use exclusive creation mode instead of check-then-create when overwrites must be prevented.

