Comment puis-je vérifier la taille d'un fichier en Python?

758

J'écris un script Python sous Windows. Je veux faire quelque chose en fonction de la taille du fichier. Par exemple, si la taille est supérieure à 0, j'enverrai un e-mail à quelqu'un, sinon je continuerai avec autre chose.

Comment vérifier la taille du fichier?

5YrsLaterDBA
la source
2
Path('./doc.txt').stat().st_size
Boris
Merci @Boris pour la réponse Python (v3.4 +) moderne :)
mab

Réponses:

735

Vous avez besoin de la st_sizepropriété de l'objet retourné paros.stat . Vous pouvez l'obtenir soit en utilisant pathlib(Python 3.4+):

>>> from pathlib import Path
>>> Path('somefile.txt').stat()
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> Path('somefile.txt').stat().st_size
1564

ou en utilisant os.stat:

>>> import os
>>> os.stat('somefile.txt')
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> os.stat('somefile.txt').st_size
1564

La sortie est en octets.

Adam Rosenfield
la source
2
Le cas échéant, la valeur peut être transmise sous forme de multiples de la taille de bloc du système de fichiers (4096 octets par exemple). Heureusement, il est plutôt donné en octets.
josch
1
@josch - oui, c'est bien, pour la "taille sur le disque", vous pouvez multiplier stat_result.st_blockspar la taille du bloc, mais je cherche toujours comment l'obtenir par programme et multiplateforme (pas via tune2fsetc.)
Tomasz Gandor
1099

En utilisant os.path.getsize:

>>> import os
>>> b = os.path.getsize("/path/isa_005.mp3")
>>> b
2071611

La sortie est en octets.

danben
la source
124
Remarque: l'implémentation de os.path.getsizeest tout simplementreturn os.stat(filename).st_size
wim
Y a-t-il donc une perte de performances minime en utilisant os.path.getsize par opposition à os.stat (fichier) .st_size?
mots pour
5
@wordsforthewise le mesurer! ~ 150 ns sur mon ordinateur.
Davidmh
@wordsforthewise c'est plus un problème si vous souhaitez également obtenir d'autres informations sur le fichier (heure de modification, type de fichier, par exemple) - alors vous pouvez tout aussi bien obtenir tout cela d'un seul appel système via os.stat. La différence pourrait alors
atteindre
S'il est appelé juste après la création d'un fichier, il renvoie 0 @danben
alper
131

Les autres réponses fonctionnent pour de vrais fichiers, mais si vous avez besoin de quelque chose qui fonctionne pour des "objets de type fichier", essayez ceci:

# f is a file-like object. 
f.seek(0, os.SEEK_END)
size = f.tell()

Cela fonctionne pour de vrais fichiers et StringIO, dans mes tests limités. (Python 2.7.3.) L'API "objet de type fichier" n'est pas vraiment une interface rigoureuse, bien sûr, mais la documentation de l' API suggère que les objets de type fichier devraient prendre en charge seek()et tell().

Éditer

Une autre différence entre cela et os.stat()c'est que vous pouvez stat()un fichier même si vous n'avez pas la permission de le lire. De toute évidence, l'approche de recherche / tell ne fonctionnera pas à moins d'avoir une autorisation de lecture.

Modifier 2

À la suggestion de Jonathon, voici une version paranoïaque. (La version ci-dessus laisse le pointeur de fichier à la fin du fichier, donc si vous essayez de lire le fichier, vous ne récupérerez aucun octet!)

# f is a file-like object. 
old_file_position = f.tell()
f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(old_file_position, os.SEEK_SET)
Mark E. Haase
la source
8
Vous n'avez pas besoin d'importer os, écrivez f.seek(0, 2)à la place pour rechercher 0 octet à la fin.
cdosborn
2
Et pour la dernière ligne, si elle osn'est pas utilisée:f.seek(old_file_position, 0)
luckydonald
48
Si vous utilisez des littéraux entiers au lieu de variables nommées, vous torturez quiconque doit maintenir votre code. Il n'y a aucune raison impérieuse de ne pas importer os.
Mark E. Haase
Merci pour la solution, j'ai implémenté et ça fonctionne bien. Juste pour confirmer, la sizesortie est en octets?
Kedar.Aitawdekar
3
Apparemment, cela est au moins un peu risqué, selon la façon dont Python implémente #seek(): wiki.sei.cmu.edu/confluence/display/c/…
Autumnsault
72
import os


def convert_bytes(num):
    """
    this function will convert bytes to MB.... GB... etc
    """
    for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
        if num < 1024.0:
            return "%3.1f %s" % (num, x)
        num /= 1024.0


def file_size(file_path):
    """
    this function will return the file size
    """
    if os.path.isfile(file_path):
        file_info = os.stat(file_path)
        return convert_bytes(file_info.st_size)


# Lets check the file size of MS Paint exe 
# or you can use any file path
file_path = r"C:\Windows\System32\mspaint.exe"
print file_size(file_path)

Résultat:

6.1 MB
Rajiv Sharma
la source
5
this function will convert bytes to MB.... GB... etcFaux. Cette fonction convertira les octets en MiB, GiB, etc. Voir cet article .
moi
2
La ligne 10 peut être modifiée return f'{num:.1f} {x}'en Python> = 3.5.
Matt M.
53

Utilisation pathlib( ajouté en Python 3.4 ou un backport disponible sur PyPI ):

from pathlib import Path
file = Path() / 'doc.txt'  # or Path('./doc.txt')
size = file.stat().st_size

Ce n'est vraiment qu'une interface os.stat, mais l'utilisation pathlibfournit un moyen facile d'accéder à d'autres opérations liées aux fichiers.

pumazi
la source
18

Il y a une bitshiftastuce que j'utilise si je veux convertir à partir bytesde n'importe quelle autre unité. Si vous effectuez un décalage à droite, 10vous le décalez essentiellement par un ordre (multiple).

Exemple: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)
user1767754
la source
9
Cela ne répond pas à la question. La question est de trouver la taille d'un fichier, pas de formater le résultat pour la consommation humaine.
Will Manley
1
Ces chiffres sont faux et donc déroutants. 5 Go correspondent à 5e9 octets. Est-ce censé être une sorte d'approximation lisible par l'homme? Où utiliseriez-vous même quelque chose comme ça?
Dre
1 bit => 2 ... 2 bits => 4 ... 3 bits => 8 ... 4 bits => 16 ... 5 bits => 32 ... 6 bits => 64 ... 7 bits => 128 ... 8 bits => 256 ... 9 bits => 512 ... 10 bits => 1024 ... 1024 octets soit 1 Ko ... => 20 -bits => 1024 * 1024 = 1 048 576 octets, soit 1 024 Ko et 1 Mo ... => 30 bits => 1 024 * 1 024 * 1 024 = 1 073 741 824 octets, soit 1 048 576 Ko, 1 024 Mo et 1 Go… Vous avez confondu notation scientifique et décimales avec la représentation binaire / base-2 utilisée en informatique. 5x9 = 5 x 10 ^ 9 = 5 000 000 000
James 'Fluffy' Burton
3
Les gars, il n'a rien confondu ... il vient de donner une approximation, ce qui est évident quand il dit "fondamentalement". 2 ^ 10 est d'env. 10 ^ 3. En fait, cette approximation est si courante qu'elle a un nom : Mebi , Gibi et Tebi sont respectivement Mega, Giga et Tera. En ce qui concerne le fait de ne pas répondre à la question, @WillManley, vous avez tout à fait raison ici! ;-p
Mike Williamson
9

S'en tenir strictement à la question, le code Python (+ pseudo-code) serait:

import os
file_path = r"<path to your file>"
if os.stat(file_path).st_size > 0:
    <send an email to somebody>
else:
    <continue to other things>
Victor Barrantes
la source
-1
#Get file size , print it , process it...
#Os.stat will provide the file size in (.st_size) property. 
#The file size will be shown in bytes.

import os

fsize=os.stat('filepath')
print('size:' + fsize.st_size.__str__())

#check if the file size is less than 10 MB

if fsize.st_size < 10000000:
    process it ....
Chikku Jacob
la source
-1

nous avons deux options Les deux incluent l'importation du module os

1) importer os en tant que fonction os.stat () renvoie un objet qui contient autant d'en-têtes, y compris l'heure de création du fichier et l'heure de la dernière modification, etc. parmi eux st_size () donne la taille exacte du fichier.

os.stat ("nom de fichier"). st_size ()

2) import os Dans ce cas, nous devons fournir le chemin exact du fichier (chemin absolu), pas un chemin relatif.

os.path.getsize ("chemin du fichier")

gunarevuri
la source