Mesurer la taille d’un fichier en Python paraît simple, mais le bon choix dépend vite du contexte: fichier local, lien symbolique, dossier, ou traitement en lot. Le besoin derrière python get file size est presque toujours le même: récupérer une taille fiable en octets, sans lire tout le contenu. Je vais aller droit au point avec les méthodes utiles, les cas où elles divergent et les pièges qui font perdre du temps.
Ce qu’il faut garder en tête
-
os.path.getsize()est la voie la plus directe pour un fichier local. -
Path.stat().st_sizeest souvent plus lisible si votre code utilise déjàpathlib. -
st_sizemesure une taille logique en octets, pas forcément l’espace réellement occupé sur disque. - Un lien symbolique, un dossier et un fichier manquant ne se traitent pas de la même façon.
- Pour afficher la taille à l’utilisateur, convertissez ensuite les octets dans une unité lisible.
La méthode la plus directe pour un fichier local
Si vous voulez juste la taille d’un fichier sur disque, j’utilise d’abord os.path.getsize().
import os
taille_octets = os.path.getsize("data/rapport.pdf")
print(f"{taille_octets} octets")Cette fonction renvoie la taille en octets et lève OSError si le chemin est inaccessible ou si le fichier n’existe pas. La documentation officielle de Python la présente comme la solution la plus simple quand on n’a pas besoin d’en savoir plus sur les métadonnées du fichier.
En pratique, j’apprécie cette version quand le code doit rester court et lisible. Si vous avez besoin d’un contrôle plus fin sur les erreurs, enveloppez l’appel dans un try/except plutôt que de tester l’existence du fichier juste avant: entre les deux opérations, le fichier peut disparaître.
import os
chemin = "data/rapport.pdf"
try:
taille_octets = os.path.getsize(chemin)
except FileNotFoundError:
print("Le fichier est introuvable.")
except PermissionError:
print("Accès refusé.")
except OSError as exc:
print(f"Erreur lors de la lecture de la taille: {exc}")Cette approche couvre déjà la majorité des besoins simples, mais dès que votre projet manipule des chemins sous forme d’objets, pathlib devient souvent plus confortable.
Pourquoi pathlib est souvent plus propre
pathlib m’intéresse surtout quand le projet mélange des chemins, des concaténations et quelques opérations de stat. Avec Path.stat().st_size, on garde une lecture plus homogène du code.
from pathlib import Path
fichier = Path("data/rapport.pdf")
taille_octets = fichier.stat().st_size
print(f"{taille_octets} octets")La méthode renvoie un objet stat_result, puis on lit l’attribut st_size. Le point important est simple: Path.stat() suit les liens symboliques par défaut. Si vous voulez la taille du lien lui-même, il faut utiliser Path.lstat() à la place.
from pathlib import Path
lien = Path("data/lien-vers-rapport")
print(lien.stat().st_size) # taille de la cible
print(lien.lstat().st_size) # taille du lien symboliqueDans les projets modernes, je privilégie souvent pathlib dès qu’il faut enchaîner d’autres opérations sur le même chemin. On garde un style plus lisible, et le code s’étend mieux quand la logique devient un peu plus riche.
Quand plusieurs approches sont disponibles, la vraie question devient celle du compromis: lisibilité, compatibilité et volume de fichiers.
Comment choisir entre les principales approches
Pour moi, le choix tient surtout à deux critères: la forme de votre code et le type d’opération que vous faites autour de la taille. Si vous ne faites qu’une lecture ponctuelle, la fonction la plus courte gagne. Si le chemin sert à plusieurs opérations, pathlib prend l’avantage.
| Méthode | Quand l’utiliser | Avantage principal | Limite à garder en tête |
|---|---|---|---|
os.path.getsize(path) |
Lecture rapide d’un fichier local | Très direct et facile à comprendre | Moins pratique si le reste du code utilise Path
|
Path(path).stat().st_size |
Projet déjà orienté pathlib
|
Chaînage naturel avec d’autres opérations sur le chemin | Un peu plus verbeux pour un besoin minimal |
os.stat(path).st_size |
Besoin d’accéder à d’autres métadonnées dans le même appel | Accès direct à tout le bloc stat
|
Moins lisible si seule la taille vous intéresse |
os.walk() |
Mesure d’une arborescence entière | Adapté aux dossiers et aux lots de fichiers | Ne sert pas pour un simple fichier unique |
La documentation officielle de Python insiste aussi sur un point utile en production: os.walk() s’appuie sur os.scandir(), ce qui réduit le nombre d’appels système. Ce détail compte dès que vous parcourez un répertoire un peu large.
Autrement dit, la bonne méthode n’est pas celle qui “fait le plus Python”, mais celle qui correspond vraiment au scénario. Une fois ce choix posé, il reste à décider comment présenter la valeur à l’écran.
Afficher une taille lisible sans brouiller la précision
La sortie brute en octets est correcte, mais rarement confortable pour un humain. Pour un rapport, une interface ou un log d’exploitation, je convertis presque toujours la valeur en unités plus lisibles.
def format_taille(octets: int) -> str:
unites = ["octets", "Kio", "Mio", "Gio", "Tio"]
valeur = float(octets)
for unite in unites:
if valeur < 1024 or unite == unites[-1]:
return f"{valeur:.1f} {unite}" if unite != "octets" else f"{int(valeur)} octets"
valeur /= 1024
print(format_taille(1536))J’utilise ici une base 1024, parce qu’elle colle mieux à la logique technique des systèmes de fichiers. Si votre produit doit suivre une convention commerciale ou marketing, alignez-vous sur cette convention et non sur celle du code.
Le point clé est de ne pas confondre l’unité d’affichage avec la mesure elle-même: la taille originale reste en octets, et la conversion ne sert qu’à la rendre plus lisible.
Reste un point qui provoque souvent des erreurs discrètes: ce que la taille mesure exactement.
Les pièges qui faussent la lecture
La taille renvoyée par st_size est la taille logique du fichier. Ce n’est pas toujours la même chose que l’espace réellement occupé sur disque, surtout avec des fichiers clairsemés, de la compression ou certaines particularités de système de fichiers. Sur des systèmes Unix compatibles, Python expose aussi st_blocks, que la documentation décrit comme le nombre de blocs de 512 octets alloués; il peut être inférieur à st_size / 512 quand le fichier contient des trous.
Je fais aussi attention à trois erreurs classiques:
- tester d’abord
exists()puis appeler la lecture de taille, ce qui ajoute une fenêtre de course inutile; - oublier qu’un dossier n’est pas un fichier et ne pas le traiter séparément;
- penser qu’un lien symbolique donne toujours la taille de la cible, alors que
lstat()raconte une autre histoire.
Autre détail pratique: si un fichier change pendant la lecture, la valeur peut ne plus représenter l’état final au moment où vous l’utilisez. Pour des scripts simples, ce n’est pas dramatique; pour de la synchronisation, de l’archivage ou du contrôle d’intégrité, je préfère verrouiller le flux de traitement ou accepter qu’il s’agisse d’un instantané approximatif.
Quand on passe d’un seul fichier à un dossier entier, ces nuances deviennent beaucoup plus visibles, surtout si vous additionnez des milliers d’entrées.
Mesurer un dossier ou une arborescence entière
Si votre vrai besoin est la taille totale d’un répertoire, il faut additionner les fichiers un par un. Je préfère alors os.walk() pour sa lisibilité, en gardant en tête que la documentation officielle de Python le rend plus efficace qu’avant grâce à scandir().
import os
from os.path import getsize, join
def taille_dossier(racine: str) -> int:
total = 0
for dossier, sous_dossiers, fichiers in os.walk(racine):
for nom in fichiers:
chemin = join(dossier, nom)
if not os.path.islink(chemin):
total += getsize(chemin)
return total
print(taille_dossier("data"))Dans cette version, j’ignore les liens symboliques pour éviter les surprises ou les doubles comptages. Selon votre cas, vous pouvez choisir de les suivre, mais faites-le consciemment: dans un arbre de fichiers réel, un lien peut vous renvoyer vers un autre endroit du système et fausser le total.
Pour des arborescences volumineuses, le vrai enjeu n’est plus la syntaxe mais le coût du parcours. Si vous ne devez analyser qu’un sous-ensemble de dossiers, filtrez tôt, évitez les allers-retours inutiles et ne relancez pas des stat() superflus.
À ce stade, la question n’est plus seulement “comment récupérer la taille”, mais “quelle information cette taille doit réellement servir à prendre comme décision”.
Quand la taille ne suffit pas pour décider
Dans beaucoup de projets, la taille n’est qu’un signal parmi d’autres. Pour valider un upload, je combine souvent la taille avec l’extension, le type MIME détecté, parfois même un contrôle de contenu si le niveau de risque le justifie. Pour une tâche backend, la taille sert surtout à éviter les abus, dimensionner une file de traitement ou choisir un mode de compression.
- Validation d’upload: taille maximale + type de fichier + éventuelle lecture du contenu.
- Traitement de médias: taille logique + format + résolution ou durée.
- Archivage: taille du fichier + nombre d’éléments + ancienneté.
- Monitoring: taille instantanée + évolution dans le temps + seuils d’alerte.
Mon réflexe, en pratique, est simple: os.path.getsize() pour un besoin ponctuel, pathlib pour un code plus propre, et os.walk() quand je dois agréger plusieurs fichiers. Si vous gardez cette règle mentale, vous évitez la moitié des détours inutiles et vous choisissez plus vite la bonne lecture de la taille en Python.