¿Cómo puedo verificar el tamaño del archivo en Python?

758

Estoy escribiendo un script de Python en Windows. Quiero hacer algo en función del tamaño del archivo. Por ejemplo, si el tamaño es mayor que 0, enviaré un correo electrónico a alguien, de lo contrario, continuaré con otras cosas.

¿Cómo verifico el tamaño del archivo?

5 años más tarde
fuente
2
Path('./doc.txt').stat().st_size
Boris
Gracias @ Boris por la respuesta moderna de Python (v3.4 +) :)
mab

Respuestas:

735

Necesita la st_sizepropiedad del objeto devuelto poros.stat . Puede obtenerlo usando 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

o usando 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 salida está en bytes.

Adam Rosenfield
fuente
2
En todo caso, el valor podría pasarse como múltiplos del tamaño de bloque del sistema de archivos (4096 bytes, por ejemplo). Con mucho gusto, se da como bytes en su lugar.
josch
1
@josch - sí, esto es bueno, para el "tamaño en el disco" puede multiplicar stat_result.st_blockspor el tamaño del bloque, pero todavía estoy buscando cómo obtenerlo mediante programación y multiplataforma (no a través de tune2fsetc.)
Tomasz Gandor
1099

Utilizando os.path.getsize:

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

La salida está en bytes.

danben
fuente
124
Nota: la implementación de os.path.getsizees simplementereturn os.stat(filename).st_size
wim
Entonces, ¿hay una pérdida mínima de rendimiento al usar os.path.getsize en lugar de os.stat (file) .st_size?
wordsforthewise
55
¡@wordsforthewise lo mide! ~ 150 ns en mi computadora.
Davidmh
@wordsforthewise esto es más un problema si también desea obtener otras cosas sobre el archivo (hora de modificación, tipo de archivo, por ejemplo), entonces también podría obtenerlo todo desde una sola llamada al sistema a través de os.stat. Entonces la diferencia podría encontrarse en un número considerable de microsegundos :-)
greggo
Si se llama justo después de que se crea un archivo devuelve 0 @danben
Alper
131

Las otras respuestas funcionan para archivos reales, pero si necesita algo que funcione para "objetos similares a archivos", intente esto:

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

Funciona para archivos reales y StringIO, en mis pruebas limitadas. (Python 2.7.3.) La API "objeto tipo archivo" no es realmente una interfaz rigurosa, por supuesto, pero la documentación de la API sugiere que los objetos tipo archivo deberían admitir seek()y tell().

Editar

Otra diferencia entre esto y os.stat()es que puede stat()crear un archivo incluso si no tiene permiso para leerlo. Obviamente, el enfoque de buscar / contar no funcionará a menos que tenga permiso de lectura.

Editar 2

A sugerencia de Jonathon, aquí hay una versión paranoica. (La versión anterior deja el puntero del archivo al final del archivo, por lo que si intenta leer el archivo, ¡obtendrá cero bytes!)

# 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
fuente
8
No necesita importar os, en su lugar escriba f.seek(0, 2)para buscar 0 bytes desde el final.
cdosborn
2
Y para la última línea, si osno se usa:f.seek(old_file_position, 0)
luckydonald
48
Si usa literales enteros en lugar de variables con nombre, está torturando a cualquiera que tenga que mantener su código. No hay una razón convincente para no importar os.
Mark E. Haase
Gracias por la solución, la he implementado y está funcionando bien. Solo para confirmar, ¿la sizesalida está en bytes?
Kedar.Aitawdekar
3
Aparentemente, esto es al menos un poco arriesgado, dependiendo de cómo implemente Python #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)

Resultado:

6.1 MB
Rajiv Sharma
fuente
55
this function will convert bytes to MB.... GB... etcIncorrecto. Esta función convertirá bytes a MiB, GiB, etc. Ver esta publicación .
moi
2
La línea 10 se puede cambiar a return f'{num:.1f} {x}'en Python> = 3.5.
Matt M.
53

Usando pathlib( agregado en Python 3.4 o un puerto disponible en PyPI ):

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

Esto es realmente solo una interfaz os.stat, pero el uso pathlibproporciona una manera fácil de acceder a otras operaciones relacionadas con archivos.

pumazi
fuente
18

Hay un bitshifttruco que uso si quiero convertir de bytescualquier otra unidad. Si hace un desplazamiento a la derecha, 10básicamente lo cambia por un orden (múltiple).

Ejemplo: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)
usuario1767754
fuente
99
Esto no responde la pregunta. La pregunta es sobre encontrar el tamaño de un archivo, no sobre formatear el resultado para el consumo humano.
Will Manley
1
Estos números son incorrectos y, por lo tanto, confusos. 5GB son 5e9 bytes. ¿Se supone que esto es una especie de aproximación legible por humanos? ¿Dónde usarías algo como esto?
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 bytes es 1kB ... => 20 -bits => 1024 * 1024 = 1,048,576bytes, que es 1024kB, y 1MB ... => 30-bits => 1024 * 1024 * 1024 = 1,073,741,824 bytes, que es 1,048,576 kB, y 1024MB, y 1GB ... Has confundido Notación científica y lugares decimales con la representación binaria / base-2 utilizada en informática. 5x9 = 5 x 10 ^ 9 = 5,000,000,000
James 'Fluffy' Burton
3
Chicos, no ha confundido nada ... solo le ha dado una aproximación, lo cual es evidente cuando dice "básicamente". 2 ^ 10 es aprox. 10 ^ 3. De hecho, esta aproximación es tan común que tiene un nombre : Mebi , Gibi y Tebi son Mega, Giga y Tera, respectivamente. Con respecto a no responder la pregunta, @WillManley, ¡tienes un buen punto allí! ;-p
Mike Williamson
9

Estrictamente apegado a la pregunta, el código de Python (+ pseudocódigo) sería:

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
fuente
-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
fuente
-1

tenemos dos opciones Ambas incluyen la importación del módulo os

1) importar os como os.stat () la función devuelve un objeto que contiene muchos encabezados, incluido el tiempo de creación del archivo y el tiempo de la última modificación, etc. entre ellos st_size () proporciona el tamaño exacto del archivo.

os.stat ("nombre de archivo"). st_size ()

2) import os En esto, tenemos que proporcionar la ruta exacta del archivo (ruta absoluta), no una ruta relativa.

os.path.getsize ("ruta del archivo")

gunarevuri
fuente