By Pankaj Kumar and Manikandan Kurup
At some point in your Python journey, you’re going to need to figure out how big a file is. Whether you’re building a file uploader, managing assets, or just doing a quick check on disk space, it’s a common task that’ll come your way. The good news is that Python makes this incredibly simple. This article will walk you through the best and most common ways to get a file’s size.
We’ll start with the classic os.path.getsize()
function, the go-to for a quick and direct answer. Then, we’ll explore the more modern and elegant pathlib
approach, which is a fantastic tool to have in your belt. We’ll also cover how to handle errors gracefully when a file is missing, and finally, how to convert raw byte counts into a clean, human-readable format like “KB” or “MB”.
os.path.getsize('path/to/file')
for the most direct, standard way to get a file’s size in bytes.pathlib
module.os.stat()
when you need additional file metadata, such as the last modification time, in addition to the file’s size.try...except
block to gracefully handle potential FileNotFoundError
and PermissionError
.os.path.getsize()
For a quick and direct answer, the os.path.getsize()
function is the best choice. It’s part of Python’s standard os
module and is the most common way to get a file’s size. It does one thing and does it well: it takes a path to a file and returns its size.
It’s important to remember that the function returns the size as an integer representing the number of bytes.
import os
file_path = 'data/my_document.txt'
file_size = os.path.getsize(file_path)
print(f"The file size is: {file_size} bytes")
Output:
The file size is: 437 bytes
pathlib.Path
Introduced in Python 3.4, the pathlib
module offers a modern, object-oriented way to handle filesystem paths. If you’re writing new code, this is often the recommended approach because it makes your code more readable and expressive. Instead of working with plain strings, you create a Path
object that has its own methods, including one for getting file stats.
To get the size, you call the .stat()
method on your Path
object, which returns a result object (similar to os.stat()
), and then you access its .st_size
attribute.
from pathlib import Path
file_path = Path('data/my_document.txt')
file_size = file_path.stat().st_size
print(f"The file size is: {file_size} bytes")
Output:
The file size is: 437 bytes
os.stat()
When you need more than just the size of a file, os.stat()
function is the tool for the job. While os.path.getsize()
is a convenient shortcut, os.stat()
is the underlying function that retrieves a full “status” report on the file. This report is an object containing a wealth of metadata.
The file size is available via the st_size
attribute of the result object. This method is perfect when you also need to know things like the file’s last modification time (st_mtime
) or creation time (st_ctime
).
import os
import datetime
file_path = 'data/my_document.txt'
stat_info = os.stat(file_path)
file_size = stat_info.st_size
mod_time_timestamp = stat_info.st_mtime
mod_time = datetime.datetime.fromtimestamp(mod_time_timestamp)
print(f"File Size: {file_size} bytes")
print(f"Last Modified: {mod_time.strftime('%Y-%m-%d %H:%M:%S')}")
Output:
File Size: 437 bytes
Last Modified: 2025-07-16 17:42:05
From the previous examples, you may have noticed that the file sizes are always returned in bytes. While getting the file size in bytes is technically accurate, a number like 1474560 doesn’t mean much to most people at a glance. Is that big? Is it small? For a better user experience, it’s essential to convert this raw byte count into a more familiar format, like kilobytes (KB), megabytes (MB), or gigabytes (GB).
This is easily done with a small helper function. The logic is simple: we repeatedly divide the number of bytes by 1024 (the number of bytes in a kilobyte) and keep track of the unit until the number is small enough to be readable.
Here is a function that handles this conversion gracefully and can be integrated directly into your code.
This function takes the size in bytes and an optional number of decimal places for formatting.
def format_size(size_bytes, decimals=2):
if size_bytes == 0:
return "0 Bytes"
# Define the units and the factor for conversion (1024)
power = 1024
units = ["Bytes", "KB", "MB", "GB", "TB", "PB"]
# Calculate the appropriate unit
import math
i = int(math.floor(math.log(size_bytes, power)))
# Format the result
return f"{size_bytes / (power ** i):.{decimals}f} {units[i]}"
Let’s use it in an example:
import os
file_path = 'data/large_file.zip'
raw_size = os.path.getsize(file_path)
readable_size = format_size(raw_size)
print(f"Raw size: {raw_size} bytes")
print(f"Human-readable size: {readable_size}")
Output:
Raw size: 1474560 bytes
Human-readable size: 1.41 MB
By integrating a simple function like this, you can make your program’s output significantly more intuitive and professional.
In a perfect world, every file path would be correct and every file accessible. But in reality, things go wrong. Your script might try to access a file that has been moved, or it might not have the permissions to read it. Without proper error handling, these situations will crash your program. A robust script anticipates these issues and handles them gracefully.
Let’s see how to handle the most common errors you’ll encounter when getting a file’s size.
FileNotFoundError
This is the most common error you’ll face. It occurs when you try to get the size of a file that doesn’t exist at the specified path. Wrapping your code in a try...except FileNotFoundError
block is the standard way to manage this.
import os
file_path = 'path/to/non_existent_file.txt'
try:
file_size = os.path.getsize(file_path)
print(f"File size: {file_size} bytes")
except FileNotFoundError:
print(f"Error: The file at '{file_path}' was not found.")
PermissionError
Sometimes the file exists, but your script doesn’t have the necessary operating system permissions to read it or its metadata. This will raise a PermissionError
. You can catch this error specifically to give a more informative message to the user.
import os
file_path = '/root/secure_file.dat'
try:
file_size = os.path.getsize(file_path)
print(f"File size: {file_size} bytes")
except FileNotFoundError:
print(f"Error: The file at '{file_path}' was not found.")
except PermissionError:
print(f"Error: Insufficient permissions to access '{file_path}'.")
Symbolic links (or symlinks) are pointers to other files. What happens if a symlink points to a file that has been deleted? The link itself exists, but it’s “broken.” Calling os.path.getsize()
on a broken symlink will raise an OSError
.
A good practice is to first check if the path is a link and then resolve its actual path before getting the size.
import os
symlink_path = 'data/broken_link.txt'
try:
file_size = os.path.getsize(symlink_path)
print(f"File size: {file_size} bytes")
except FileNotFoundError:
print(f"Error: The file pointed to by '{symlink_path}' was not found.")
except OSError as e:
print(f"OS Error: Could not get size for '{symlink_path}'. It may be a broken link. Details: {e}")
Note: A broken symlink might raise FileNotFoundError
on some operating systems.
By catching these specific exceptions, you make your code more resilient and user-friendly, providing clear feedback when something goes wrong instead of just crashing.
The most straightforward way to get the size of a file in Python is by using the os.path.getsize()
function. This function is part of the built-in os module and returns the size of the file in bytes. Here’s a quick example:
import os
file_size = os.path.getsize('data/example.txt')
print(f"File size: {file_size} bytes")
This method works well for most use cases where you just need a fast and simple byte count.
os.path.getsize()
and os.stat()
?While both functions return file size, they serve different purposes. os.path.getsize()
is a convenience function that returns only the size in bytes. In contrast, os.stat()
provides a full status object (stat_result
) that includes various metadata such as:
st_size
: file size in bytesst_mtime
: last modification timest_ctime
: creation time (or metadata change time, depending on the OS)Example:
import os
stat = os.stat('data/example.txt')
print(f"Size: {stat.st_size} bytes, Last Modified: {stat.st_mtime}")
Use os.stat()
when you need more than just the size.
pathlib
instead of os.path
for file size?Yes, especially in modern Python code (version 3.4 and above). The pathlib
module provides an object-oriented interface for file system operations. It improves readability and is considered more Pythonic.
Instead of working with plain strings, you work with Path
objects:
from pathlib import Path
file_path = Path('data/example.txt')
file_size = file_path.stat().st_size
This approach is cross-platform, cleaner, and integrates well with other modern Python features.
Raw byte counts can be hard to interpret, especially for larger files. To display sizes in a human-readable format, you can use a helper function that divides the size by 1024 repeatedly and appends the correct unit:
def format_size(size_bytes, decimals=2):
if size_bytes == 0:
return "0 Bytes"
power = 1024
units = ["Bytes", "KB", "MB", "GB", "TB", "PB"]
import math
i = int(math.floor(math.log(size_bytes, power)))
return f"{size_bytes / (power ** i):.{decimals}f} {units[i]}"
Using this function, 1474560 bytes would become 1.41 MB, which is much more user-friendly.
If the file path is incorrect or the file doesn’t exist, Python will raise a FileNotFoundError
. If the file exists but your script doesn’t have permission to access it, a PermissionError
is raised. To prevent your program from crashing, wrap the operation in a try...except
block:
try:
size = os.path.getsize('some/file.txt')
except FileNotFoundError:
print("The file does not exist.")
except PermissionError:
print("You do not have permission to access this file.")
This ensures your program handles errors gracefully and provides helpful feedback.
If the symbolic link points to a valid file, os.path.getsize()
will return the size of the target file. However, if the symlink is broken (i.e., the target no longer exists), calling this function will raise a FileNotFoundError
or OSError
, depending on the operating system.
To avoid this, you can check if the path is a symlink and whether its target exists:
import os
if os.path.islink('link.txt') and os.path.exists(os.readlink('link.txt')):
size = os.path.getsize('link.txt')
else:
print("Broken symbolic link or target not found.")
This way, you can handle broken symlinks gracefully.
You now know how to get a file’s size in Python using the direct os.path.getsize()
, the modern pathlib
module, or the more detailed os.stat()
function. We also covered how to handle errors and convert byte counts into a human-readable format. While the simpler methods work well, remember that pathlib
is the recommended standard for writing robust, maintainable code.
To build on these skills, you can explore how to handle plain text files to read and write data or build a complete command-line utility by handling user arguments.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Java and Python Developer for 20+ years, Open Source Enthusiast, Founder of https://www.askpython.com/, https://www.linuxfordevices.com/, and JournalDev.com (acquired by DigitalOcean). Passionate about writing technical articles and sharing knowledge with others. Love Java, Python, Unix and related technologies. Follow my X @PankajWebDev
With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers.
Thanks for the example. It was helpful. As an FYI I use a mac os version 10.15.5. The get info feature of Finder reports file size in multiples of 1,000,000 ( 1000 * 1000) not 1,048,596 (1024 * 1024). Not sure if this changed at some point. Thanks again
- John
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.