Come posso controllare la dimensione del file in Python?


757

Sto scrivendo uno script Python in Windows. Voglio fare qualcosa in base alla dimensione del file. Ad esempio, se la dimensione è maggiore di 0, invierò un'email a qualcuno, altrimenti continuerò ad altre cose.

Come posso controllare le dimensioni del file?


2
Path('./doc.txt').stat().st_size
Boris,

Grazie @Boris per la moderna risposta Python (v3.4 +) :)
martedì

Risposte:


735

È necessaria la st_sizeproprietà dell'oggetto restituito daos.stat . Puoi ottenerlo utilizzando 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

L'output è in byte.


2
Semmai, il valore potrebbe essere passato come multipli della dimensione del blocco del file system (ad esempio 4096 byte). Volentieri, è invece dato come byte.
luglio

1
@josch - sì, è bello, per la "dimensione su disco" puoi moltiplicare stat_result.st_blocksper la dimensione del blocco, ma sto ancora cercando come ottenerlo programmaticamente e multipiattaforma (non tramite tune2fsecc.)
Tomasz Gandor

1099

Utilizzando os.path.getsize:

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

L'output è in byte.


124
Nota: l'implementazione di os.path.getsizeè semplicementereturn os.stat(filename).st_size
wim

Quindi c'è una minima perdita di prestazioni dall'uso di os.path.getsize rispetto a os.stat (file) .st_size?
parole per

5
@wordsforthewise misuralo! ~ 150 ns nel mio computer.
Davidmh,

@wordsforthewise questo è più di un problema se vuoi anche ottenere altre cose sul file (tempo di modifica, tipo di file, ad esempio) - allora potresti anche ottenere tutto da una singola chiamata di sistema tramite os.stat. Quindi la differenza potrebbe incorrere in un numero considerevole di microsecondi :-)
greggo

Se viene chiamato subito dopo viene creato un file restituisce 0 @danben
Alper

131

Le altre risposte funzionano per file reali, ma se hai bisogno di qualcosa che funzioni per "oggetti simili a file", prova questo:

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

Funziona con file reali e StringIO, nei miei test limitati. (Python 2.7.3.) L'API "oggetto simile a un file" non è in realtà un'interfaccia rigorosa, ovviamente, ma la documentazione dell'API suggerisce che gli oggetti simili a file dovrebbero supportare seek()e tell().

modificare

Un'altra differenza tra questo ed os.stat()è che è possibile stat()un file anche se non si dispone dell'autorizzazione per leggerlo. Ovviamente l'approccio seek / tell non funzionerà se non si dispone dell'autorizzazione di lettura.

Modifica 2

Su suggerimento di Jonathon, ecco una versione paranoica. (La versione sopra lascia il puntatore del file alla fine del file, quindi se dovessi provare a leggere dal file, otterrai zero byte indietro!)

# 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)

8
Non è necessario importare os, invece scrivere f.seek(0, 2)per cercare 0 byte dalla fine.
cdosborn,

2
E per l'ultima riga, se osnon utilizzato:f.seek(old_file_position, 0)
luckydonald

48
Se usi valori letterali interi anziché variabili con nome, stai torturando chiunque debba mantenere il tuo codice. Non ci sono motivi validi per non importare os.
Mark E. Haase,

Grazie per la soluzione, l'ho implementata e funziona bene. Solo per confermare, l' sizeoutput è in byte?
Kedar.Aitawdekar,

3
Apparentemente questo è almeno un po 'rischioso, a seconda di come Python implementa #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)

Risultato:

6.1 MB

5
this function will convert bytes to MB.... GB... etcSbagliato. Questa funzione converte i byte in MiB, GiB, ecc. Vedi questo post .
moi,

2
La riga 10 può essere cambiata return f'{num:.1f} {x}'in Python> = 3.5.
Matt M.

53

Utilizzando pathlib( aggiunto in Python 3.4 o un backport disponibile su PyPI ):

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

Questa è davvero solo un'interfaccia in giro os.stat, ma l'utilizzo pathlibfornisce un modo semplice per accedere ad altre operazioni relative ai file.


18

C'è un bitshifttrucco che uso se voglio convertire da bytesqualsiasi altra unità. Se fai uno spostamento corretto, lo sposti 10sostanzialmente di un ordine (multiplo).

Esempio: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)

9
Questo non risponde alla domanda. La domanda riguarda la ricerca della dimensione di un file, non la formattazione del risultato per il consumo umano.
Will Manley,

1
Questi numeri sono sbagliati e quindi confusi. 5 GB è 5e9 byte. Questa dovrebbe essere una sorta di approssimazione leggibile dall'uomo? Dove useresti qualcosa del genere?
Dre

1 bit => 2 ... 2 bit => 4 ... 3 bit => 8 ... 4 bit => 16 ... 5 bit => 32 ... 6 bit => 64 ... 7 bit => 128 ... 8 bit => 256 ... 9 bit => 512 ... 10 bit => 1024 ... 1024 byte è 1kB ... => 20 -bit => 1024 * 1024 = 1.048.576 byte, ovvero 1024 kB e 1 MB ... => 30 bit => 1024 * 1024 * 1024 = 1.073.741.824 byte, ovvero 1.048.576 kB e 1024 MB e 1 GB ... notazione scientifica e cifre decimali con la rappresentazione binaria / base-2 utilizzata nell'informatica. 5x9 = 5 x 10 ^ 9 = 5.000.000.000
James 'Fluffy' Burton,

3
Ragazzi, non ha confuso nulla ... gli è appena stata data un'approssimazione, il che è evidente quando dice "sostanzialmente". 2 ^ 10 è di ca. 10 ^ 3. In effetti, questa approssimazione è così comune che ha un nome : Mebi , Gibi e Tebi sono rispettivamente Mega, Giga e Tera. Per quanto riguarda il non rispondere alla domanda, @WillManley, hai ragione! ;-p
Mike Williamson,

9

Attenendosi strettamente alla domanda, il codice Python (+ pseudo-codice) sarebbe:

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>

-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 ....

-1

abbiamo due opzioni Entrambe includono l'importazione del modulo os

1) import os come funzione os.stat () restituisce un oggetto che contiene così tante intestazioni tra cui l'ora di creazione del file e l'ora dell'ultima modifica ecc. Tra queste st_size () fornisce la dimensione esatta del file.

os.stat ( "nomefile"). st_size ()

2) import os In questo, dobbiamo fornire il percorso esatto del file (percorso assoluto), non un percorso relativo.

os.path.getsize ("percorso del file")

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.