How to check if a file is empty in Python

Learn to check if a file is empty in Python. Discover various methods, tips, real-world uses, and how to debug common errors.

How to check if a file is empty in Python
Published on: 
Tue
Mar 10, 2026
Updated on: 
Fri
Mar 13, 2026
The Replit Team

To check if a file is empty in Python is a frequent task for data validation and file management workflows. Python provides simple methods to verify a file’s status before you read or write data.

In this article, you'll explore several techniques to check for an empty file. You will find practical tips, see real-world applications, and get advice to debug common issues for robust file operations.

Using os.stat() to check file size

import os
file_path = "example.txt"
is_empty = os.stat(file_path).st_size == 0
print(f"Is the file empty? {is_empty}")--OUTPUT--Is the file empty? True

The os.stat() function retrieves file system metadata without reading the entire file into memory. This makes it a highly efficient way to check a file's status, especially for large files. The function returns a stat result object containing various file attributes.

You can determine if a file is empty by checking the st_size attribute of this object, which holds the file's size in bytes. A value of 0 confirms the file is empty, making the expression os.stat(file_path).st_size == 0 evaluate to True.

File size checking techniques

Besides using os.stat(), you can also check a file's size with the os.path.getsize() function, manipulate the file pointer, or simply try to read its contents.

Using os.path.getsize() function

import os.path
file_path = "example.txt"
is_empty = os.path.getsize(file_path) == 0
print(f"Is the file empty? {is_empty}")--OUTPUT--Is the file empty? True

The os.path.getsize() function offers a more direct way to check a file's size. It's a dedicated function within the os.path module that returns a file's size in bytes. You can determine if a file is empty by simply comparing its output to 0.

  • Like os.stat(), this method is highly efficient because it only inspects file metadata without reading the file's contents.
  • The expression os.path.getsize(file_path) == 0 evaluates to True if the file has no content.

Using file pointer positions with seek() and tell()

with open("example.txt", "r") as file:
   file.seek(0, 2)  # Move to the end of the file
   is_empty = file.tell() == 0
   print(f"Is the file empty? {is_empty}")--OUTPUT--Is the file empty? True

This technique uses the file's internal pointer to check for content. You first open the file and move the pointer directly to the end.

  • The seek(0, 2) method accomplishes this. It seeks a position with an offset of 0 bytes from the file's end, which is indicated by the argument 2.
  • Next, tell() reports the pointer's current position in bytes from the start of the file.

If the end of the file is at position 0, you know it's empty. This method is less efficient than checking metadata because it requires opening the file.

Reading file content to check emptiness

with open("example.txt", "r") as file:
   content = file.read()
   is_empty = len(content) == 0
   print(f"Is the file empty? {is_empty}")--OUTPUT--Is the file empty? True

Another way to check for an empty file is to read its contents directly. The read() method loads the entire file into a string. You can then use len() to check if the string's length is 0, which confirms the file has no content.

  • While this method is straightforward, it can be inefficient.
  • Reading the whole file into memory uses more resources than checking metadata, making it less ideal for large files.

Modern and robust approaches

Building on those size-checking methods, you can write more robust code by using context managers, handling errors with try/except, and leveraging the modern pathlib library.

Using context managers with first character check

def is_file_empty(file_path):
   with open(file_path, 'r') as file:
       first_char = file.read(1)
       return not bool(first_char)
       
print(f"Is the file empty? {is_file_empty('example.txt')}")--OUTPUT--Is the file empty? True

This approach is a memory-efficient optimization. Instead of loading the entire file, you only read the very first character using file.read(1). The logic is wrapped in a with statement, which automatically handles closing the file.

  • If the file has content, read(1) returns a character. The expression not bool(first_char) then evaluates to False.
  • If the file is empty, read(1) returns an empty string. Since an empty string is falsy, not bool('') evaluates to True, confirming the file is empty.

Implementing error handling with try/except

import os
try:
   is_empty = os.path.getsize("example.txt") == 0
   print(f"Is the file empty? {is_empty}")
except FileNotFoundError:
   print("File does not exist!")
except PermissionError:
   print("No permission to access the file!")--OUTPUT--Is the file empty? True

Real-world file operations can fail for many reasons, so it's smart to wrap your logic in a try/except block. This makes your code robust by handling errors that would otherwise crash the script. For example, your program won't stop if the file you're checking doesn't exist.

  • The except FileNotFoundError: block catches this specific error, allowing you to print a helpful message.
  • Likewise, except PermissionError: handles cases where your script doesn't have the rights to access the file.

Using pathlib for object-oriented file operations

from pathlib import Path
file_path = Path("example.txt")
is_empty = file_path.stat().st_size == 0
print(f"Is the file empty? {is_empty}")--OUTPUT--Is the file empty? True

The pathlib module offers a modern, object-oriented approach to file system paths. Instead of handling file paths as simple strings, you create a Path object. This object bundles path-related functionality, making your code more readable and intuitive.

  • You can call the .stat() method directly on the Path object to access its metadata.
  • The logic remains the same—you check if the st_size attribute is 0—but the syntax is cleaner and it's often preferred in modern Python code.

Move faster with Replit

Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.

For the file-checking techniques we've explored, like using os.path.getsize() or the pathlib module, Replit Agent can turn them into production-ready tools:

  • Build a data ingestion pipeline that automatically validates and rejects empty uploaded files before they enter a database.
  • Create a system monitoring utility that alerts you if critical log files are empty, signaling a potential service failure.
  • Deploy a web application that falls back to a default configuration if a user-provided settings file is empty.

Describe your app idea, and Replit Agent writes the code, tests it, and fixes issues automatically, all in your browser.

Common errors and challenges

When checking for empty files, you might encounter subtle issues like whitespace-only files, resource leaks, or problems with binary data.

A file containing only spaces, tabs, or newlines isn't technically empty—its size is greater than zero. Because of this, size-checking methods like os.path.getsize() will report it as non-empty, which may not be the behavior you intend. To correctly identify these files, you need to inspect their content. You can read the file and call the .strip() method on the resulting string; if the output is empty, you've confirmed the file contains nothing but whitespace.

Any method that requires opening a file carries the risk of a resource leak if the file isn't closed properly. This can happen if your script encounters an error after the file is opened but before it's closed, leaving the file locked or consuming system resources. The most reliable way to prevent this is to use a with statement. This context manager guarantees that the file is automatically closed as soon as the block is exited, regardless of whether it completed successfully or raised an error.

Checking the size of binary files, such as images or executables, is simple. Functions like os.path.getsize() work just as well because they only count the file's bytes. The challenge arises when you try to read the file's content. Opening a binary file in the default text mode ('r') will likely cause a UnicodeDecodeError if it contains bytes that don't map to valid characters. To avoid this, always open non-text files in binary mode ('rb'). The content will be read as a bytes object, but you can still check its length to determine if it's empty.

Distinguishing empty files from whitespace-only files with .strip()

A file containing only spaces or newlines isn't truly empty, so size-based checks will report it as non-empty. To correctly identify these files, you must inspect their content. The following function demonstrates how a simple length check can be misleading.

def is_empty(file_path):
   with open(file_path, "r") as file:
       content = file.read()
       return len(content) == 0

print(is_empty("whitespace.txt"))  # File with only spaces and newlines

Because whitespace characters have a length, the is_empty function incorrectly returns False. The following example adjusts the logic to properly handle files that only contain whitespace.

def is_empty(file_path):
   with open(file_path, "r") as file:
       content = file.read().strip()
       return len(content) == 0

print(is_empty("whitespace.txt"))  # File with only spaces and newlines

By chaining the .strip() method to file.read(), you remove all leading and trailing whitespace. If the file only contains spaces or newlines, the resulting string becomes empty, and len(content) == 0 correctly evaluates to True. This approach is vital for data validation where a file with only whitespace should be treated as empty—a nuance that size-based checks would otherwise miss.

Avoiding resource leaks when checking file size

When you open a file, your operating system allocates resources to manage it. Failing to release these resources by not closing the file can lead to a resource leak, which can lock the file or exhaust system memory over time.

The following code demonstrates how this can happen unintentionally. While the script works, the file handle is never explicitly closed, creating a potential leak.

file_path = "example.txt"
file = open(file_path, "r")
file.seek(0, 2)  # Move to the end of the file
is_empty = file.tell() == 0
print(f"Is the file empty? {is_empty}")
# File handle remains open - resource leak!

This code is risky because it never closes the file handle. If an error occurs after you call open(), the operating system keeps the file locked. See how to prevent this with the corrected approach below.

file_path = "example.txt"
with open(file_path, "r") as file:
   file.seek(0, 2)  # Move to the end of the file
   is_empty = file.tell() == 0
print(f"Is the file empty? {is_empty}")

By wrapping the file operation in a with statement, you create a context manager. This is the key to preventing resource leaks because it automatically closes the file as soon as the block is exited. It doesn't matter if your code runs successfully or hits an error; the file is guaranteed to be closed. This makes your script more robust and is standard practice in Python for any file handling task.

Properly checking binary files for emptiness

While size-based checks work fine for binary files like images, reading their content is tricky. If you open a binary file in the default text mode ('r'), Python may raise a UnicodeDecodeError because the data doesn't map to valid characters.

The following code attempts to read an image file in text mode, which demonstrates this common pitfall.

with open("image.png", "r") as file:
   content = file.read()
   is_empty = len(content) == 0
   print(f"Is the file empty? {is_empty}")

This code triggers an error because opening the file in text mode ('r') causes read() to misinterpret the binary data. See the corrected approach below for handling these files properly.

with open("image.png", "rb") as file:
   content = file.read()
   is_empty = len(content) == 0
   print(f"Is the file empty? {is_empty}")

The fix is to open the file in binary read mode using 'rb'. This instructs Python to read the raw bytes directly instead of trying to interpret them as text characters. The read() method returns a bytes object, and you can check its length to see if it's zero. This simple change prevents a UnicodeDecodeError and is the correct way to handle any non-text file, such as an image, executable, or compressed archive.

Real-world applications

Understanding these file-checking techniques lets you build practical tools, from monitoring empty log files to creating a single, robust validation function.

Monitoring a directory for empty log files

You can build a simple monitoring script that uses os.listdir() to scan a directory and os.path.getsize() to flag empty log files, which often indicate a service issue.

import os

log_directory = "logs"
empty_logs = []

for filename in os.listdir(log_directory):
   if filename.endswith(".log"):
       filepath = os.path.join(log_directory, filename)
       if os.path.getsize(filepath) == 0:
           empty_logs.append(filename)

print(f"Empty log files: {empty_logs}")

This script automates finding empty log files within a specific directory. It iterates through all items in the logs folder and collects the names of any log files that have no content.

  • First, os.listdir() gets a list of all file and folder names.
  • The code then checks if each name .endswith(".log") to isolate the log files.
  • For each match, os.path.join() builds a full file path so that os.path.getsize() can accurately check its size.
  • If a file's size is 0, its name is added to a list, which is printed at the end.

Creating a robust is_empty() function with multiple checks

You can combine the previous methods into a single, robust is_empty() function that handles edge cases like non-existent files or files with only whitespace.

import os
from pathlib import Path

def is_empty(file_path):
   path = Path(file_path)
   
   if not path.exists():
       return "File does not exist"
   
   if path.stat().st_size == 0:
       return "File is empty (confirmed by size check)"
   
   with open(file_path, 'r') as f:
       return "File is empty (contains only whitespace)" if not f.read(1).strip() else "File has content"

print(is_empty("example.txt"))
print(is_empty("whitespace.txt"))  # A file with only spaces

This function validates a file's status by layering checks from fastest to slowest. It's a practical approach that avoids unnecessary work and handles multiple edge cases gracefully.

  • It starts with path.exists() to immediately handle missing files.
  • Next, it checks the file's metadata for a size of 0, which is highly efficient because it doesn't read the file.
  • Only if the file has a size does it open it to read the first character, distinguishing between actual content and simple whitespace.

Get started with Replit

Turn these techniques into a real tool. Tell Replit Agent to “build a utility that finds empty log files in a directory” or “create a script that validates CSV uploads and rejects empty ones”.

Replit Agent writes the code, tests for errors, and handles deployment, turning your idea into a working app. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.