You often need a file’s size before upload limits, disk budgeting, or logging. Python exposes size through os.path.getsize, os.stat, and pathlib.Path.stat; all report the same st_size in bytes for a normal file. This page gives a short quick answer, each API, comparisons, human-readable units, guards, errors, batch and folder totals, and a practical default choice.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
Quick answer: get file size in Python
For a path you trust points to a regular file, the smallest calls are os.path.getsize(path) or Path(path).stat().st_size. Both return an integer byte count.
import os
import tempfile
from pathlib import Path
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(b"hello")
name = tmp.name
try:
n = os.path.getsize(name)
m = Path(name).stat().st_size
print(n, m, n == m)
finally:
os.unlink(name)Running it prints two equal integers and True.
Get file size using os.path.getsize()
os.path.getsize takes a path string (or path-like) and returns the file size in bytes. It follows symbolic links to the target file.
import os
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(b"abcdef")
path = tmp.name
try:
print(os.path.getsize(path))
finally:
os.unlink(path)Expect 6 for the six bytes written.
Get file size using pathlib Path.stat()
Path.stat returns a os.stat_result; the st_size field is the size in bytes. This pairs well with Path.is_file() before you read or measure.
import os
import tempfile
from pathlib import Path
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(b"abc")
name = tmp.name
try:
p = Path(name)
print(p.stat().st_size)
finally:
os.unlink(name)Three bytes for "abc".
Get file size using os.stat()
os.stat returns the same structure as Path.stat() for a path string. Use it when you already work with os and want metadata (timestamps, mode) alongside size.
import os
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(b"0123456789")
path = tmp.name
try:
info = os.stat(path)
print(info.st_size)
finally:
os.unlink(path)Prints 10 for the ten-byte payload.
os.path.getsize vs pathlib vs os.stat
| API | Typical use |
|---|---|
os.path.getsize(path) |
Fast size-only lookup on a path string |
Path(path).stat().st_size |
Object-oriented paths; chain with exists() / is_file() |
os.stat(path).st_size |
Same numeric result; handy when you already read other stat fields |
getsize is implemented in terms of stat internally. Pick the style that matches the surrounding code; avoid mixing three styles in one small function without reason.
Convert file size from bytes to KB, MB, or GB
Sizes are integers in bytes. For display, divide by powers of 1024 (binary) or 1000 (decimal). Be explicit in labels (MiB-style vs MB) so users are not surprised.
def format_binary(n: int) -> str:
if n < 1024:
return f"{n} B"
for unit, denom in (("KiB", 1024), ("MiB", 1024**2), ("GiB", 1024**3)):
v = n / denom
if v < 1024 or unit == "GiB":
return f"{v:.2f} {unit}"
return f"{n} B"
print(format_binary(500))
print(format_binary(444891))Sample run: 500 B then a KiB label near 434.46 KiB for 444891 bytes.
Check file size before processing a file
Read large files in chunks or stream when possible; still check size first so you can reject oversize uploads or accidental multi-gigabyte reads early.
Check if file is empty
from pathlib import Path
import os
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as tmp:
path = tmp.name
try:
p = Path(path)
print("empty?", p.stat().st_size == 0)
finally:
os.unlink(path)An untouched empty temporary file prints empty? True. After writing bytes into the same path, st_size == 0 becomes false.
Check if file is larger than a limit
from pathlib import Path
import os
import tempfile
max_bytes = 100
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(b"x" * 200)
path = tmp.name
try:
ok = Path(path).stat().st_size <= max_bytes
print("within limit?", ok)
finally:
os.unlink(path)With 200 bytes and a limit of 100, within limit? should be False.
Handle errors while checking file size
Wrap size lookups when paths come from users or configuration. Combine with existence checks from check if a file exists and path hygiene from FileNotFoundError troubleshooting. Log oversize rejections with Python logging in upload pipelines.
File does not exist
import os
try:
print(os.path.getsize("/tmp/this-file-should-not-exist-12345.bin"))
except FileNotFoundError as exc:
print("missing:", exc.filename)Path is a directory
os.path.getsize on a directory does not give the recursive tree size; it is usually not what you want for “how big is this folder.” Test with Path.is_dir() and use the folder total pattern later in this page. Opening a directory as a normal file can raise IsADirectoryError; size APIs behave differently, so always classify the path first.
from pathlib import Path
import os
import tempfile
d = tempfile.mkdtemp()
try:
p = Path(d)
print("is_dir", p.is_dir())
print("getsize_on_dir_bytes", os.path.getsize(d))
finally:
os.rmdir(d)You should see is_dir True and a small byte value for the directory inode metadata, not the sum of nested files.
Permission denied
You may get PermissionError when the process cannot stat the file (for example system paths under tight ACLs). Handle it like other OSError subclasses.
import os
try:
os.path.getsize("/root/unlikely-readable-for-normal-user.bin")
except PermissionError:
print("no permission")
except FileNotFoundError:
print("missing")Depending on the machine, you might see missing instead if that path does not exist; the pattern is what matters for production code.
Get size of multiple files in a folder
Use a loop or comprehension over files you choose (for example one extension). Skip directories unless you intend to measure them as single entries.
import os
import tempfile
from pathlib import Path
root = Path(tempfile.mkdtemp())
(root / "a.txt").write_text("aa", encoding="utf-8")
(root / "b.txt").write_text("bbb", encoding="utf-8")
try:
total = sum(p.stat().st_size for p in root.glob("*.txt") if p.is_file())
print(total)
finally:
for p in root.glob("*"):
p.unlink()
os.rmdir(root)Five bytes total from "aa" and "bbb".
Get total size of a folder in Python
Sum st_size for every regular file under the tree. This is a simple recursive walk; for huge trees you may prefer os.scandir for speed, but pathlib.Path.rglob is clear for articles and scripts.
import os
import tempfile
from pathlib import Path
root = Path(tempfile.mkdtemp())
(root / "sub").mkdir()
(root / "sub" / "x.bin").write_bytes(b"x" * 10)
(root / "y.bin").write_bytes(b"y")
try:
total = sum(p.stat().st_size for p in root.rglob("*") if p.is_file())
print(total)
finally:
for p in sorted(root.rglob("*"), reverse=True, key=lambda x: len(x.parts)):
if p.is_file():
p.unlink()
elif p.is_dir():
p.rmdir()
root.rmdir()Expect 11 bytes from the two files.
Best method to get file size in Python
Prefer pathlib for new code: Path keeps paths structured, works cross-platform, and pairs stat() with is_file() / resolve(). Use os.path.getsize when you already have a string path and only need the integer. Avoid using seek/tell on opened files for size unless you have a stream without a path; stat is cheaper and clearer.
Summary
Read file size in bytes with os.path.getsize, os.stat(...).st_size, or Path(...).stat().st_size. Convert for display with a fixed 1024 or 1000 convention and clear units. Guard empty and oversize files before reading, catch FileNotFoundError and PermissionError, and remember directory getsize is not recursive folder usage. Sum files with rglob or os.walk for folder totals. Related: get file extension in Python.

