Wie kann ich die Dateigröße in Python überprüfen?

757

Ich schreibe ein Python-Skript in Windows. Ich möchte etwas basierend auf der Dateigröße tun. Wenn die Größe beispielsweise größer als 0 ist, sende ich eine E-Mail an jemanden, andernfalls fahren Sie mit anderen Dingen fort.

Wie überprüfe ich die Dateigröße?

5YrsLaterDBA
quelle
2
Path('./doc.txt').stat().st_size
Boris
Danke @Boris für die moderne Python (v3.4 +) Antwort :)
mab

Antworten:

735

Sie benötigen die st_sizeEigenschaft des von zurückgegebenen Objektsos.stat . Sie können es entweder mit pathlib(Python 3.4+) erhalten:

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

oder mit 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

Die Ausgabe erfolgt in Bytes.

Adam Rosenfield
quelle
2
Wenn überhaupt, könnte der Wert als Vielfaches der Blockgröße des Dateisystems übergeben werden (z. B. 4096 Byte). Gerne wird es stattdessen als Byte angegeben.
Josch
1
@josch - ja, das ist schön, für die "Größe auf der Festplatte" können Sie stat_result.st_blocksmit der Blockgröße multiplizieren , aber ich suche immer noch, wie ich es programmgesteuert und plattformübergreifend (nicht über tune2fsusw.)
bekomme
1098

Verwenden von os.path.getsize:

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

Die Ausgabe erfolgt in Bytes.

danben
quelle
124
Hinweis: Die Implementierung von os.path.getsizeist einfachreturn os.stat(filename).st_size
wim
Gibt es also einen winzigen Leistungsverlust durch die Verwendung von os.path.getsize im Gegensatz zu os.stat (Datei) .st_size?
Worte für
5
@Wordsfür messen Sie es! ~ 150 ns in meinem Computer.
Davidmh
@wordsforthewise ist dies eher ein Problem, wenn Sie auch andere Dinge über die Datei erfahren möchten (Änderungszeit, Dateityp, z. B.) - dann können Sie alles genauso gut von einem einzigen Systemaufruf über erhalten os.stat. Dann könnte der Unterschied eine beträchtliche Anzahl von Mikrosekunden
betragen
Wenn es direkt nach dem Erstellen einer Datei aufgerufen wird, gibt es 0 @danben
alper
131

Die anderen Antworten funktionieren für echte Dateien. Wenn Sie jedoch etwas benötigen, das für "dateiähnliche Objekte" funktioniert, versuchen Sie Folgendes:

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

In meinen begrenzten Tests funktioniert es für echte Dateien und StringIOs. (Python 2.7.3.) Die API "dateiähnliches Objekt" ist natürlich keine strenge Schnittstelle, aber die API-Dokumentation schlägt vor, dass dateiähnliche Objekte seek()und unterstützen sollten tell().

Bearbeiten

Ein weiterer Unterschied os.stat()besteht darin, dass Sie stat()eine Datei auch dann erstellen können, wenn Sie keine Berechtigung zum Lesen haben. Offensichtlich funktioniert der Such- / Tell-Ansatz nur, wenn Sie die Leseberechtigung haben.

Bearbeiten 2

Auf Jonathons Vorschlag hin ist hier eine paranoide Version. (In der obigen Version bleibt der Dateizeiger am Ende der Datei. Wenn Sie also versuchen, aus der Datei zu lesen, erhalten Sie null Byte zurück!)

# 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
quelle
8
Sie müssen nicht importieren os, sondern schreiben f.seek(0, 2), um 0 Bytes vom Ende zu suchen.
cdosborn
2
Und für die letzte Zeile, wenn osnicht verwendet:f.seek(old_file_position, 0)
Luckydonald
48
Wenn Sie ganzzahlige Literale anstelle von benannten Variablen verwenden, quälen Sie jeden, der Ihren Code pflegen muss. Es gibt keinen zwingenden Grund, nicht zu importieren os.
Mark E. Haase
Vielen Dank für die Lösung, die ich implementiert habe und die einwandfrei funktioniert. Nur um zu bestätigen, ist die sizeAusgabe in Bytes?
Kedar.Aitawdekar
3
Anscheinend ist dies zumindest ein wenig riskant, abhängig davon, wie Python implementiert #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)

Ergebnis:

6.1 MB
Rajiv Sharma
quelle
5
this function will convert bytes to MB.... GB... etcFalsch. Diese Funktion konvertiert Bytes in MiB, GiB usw. Siehe diesen Beitrag .
Moi
2
Zeile 10 kann return f'{num:.1f} {x}'in Python> = 3.5 geändert werden .
Matt M.
53

Verwenden pathlib( hinzugefügt in Python 3.4 oder einem auf PyPI verfügbaren Backport ):

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

Dies ist eigentlich nur eine Schnittstelle os.stat, aber die Verwendung pathlibbietet eine einfache Möglichkeit, auf andere dateibezogene Vorgänge zuzugreifen.

pumazi
quelle
18

Es gibt einen bitshiftTrick, den ich verwende, wenn ich von byteseiner anderen Einheit konvertieren möchte . Wenn Sie eine Rechtsverschiebung durchführen, verschieben 10Sie diese grundsätzlich um eine Reihenfolge (mehrere).

Beispiel: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)
user1767754
quelle
9
Dies beantwortet die Frage nicht. Bei der Frage geht es darum, die Größe einer Datei zu ermitteln und nicht darum, das Ergebnis für den menschlichen Gebrauch zu formatieren.
Will Manley
1
Diese Zahlen sind falsch und daher verwirrend. 5 GB sind 5e9 Bytes. Soll dies eine Art von lesbarer Annäherung sein? Wo würdest du so etwas überhaupt benutzen?
Dre
1 Bit => 2 ... 2 Bit => 4 ... 3 Bit => 8 ... 4 Bit => 16 ... 5 Bit => 32 ... 6 Bit => 64 ... 7 Bits => 128 ... 8 Bits => 256 ... 9 Bits => 512 ... 10 Bits => 1024 ... 1024 Bytes sind 1 kB ... => 20 -Bits => 1024 * 1024 = 1.048.576 Byte, was 1024 KB und 1 MB entspricht ... => 30 Bit => 1024 * 1024 * 1024 = 1.073.741.824 Byte, was 1.048.576 KB und 1024 MB und 1 GB entspricht ... Sie haben verwirrt wissenschaftliche Notation und Dezimalstellen mit der beim Rechnen verwendeten Binär- / Basis-2-Darstellung. 5x9 = 5 x 10 ^ 9 = 5.000.000.000
James 'Fluffy' Burton
3
Leute, er hat nichts verwirrt ... er hat nur eine Annäherung gegeben, was offensichtlich ist, wenn er "im Grunde" sagt. 2 ^ 10 ist ca. 10 ^ 3. Tatsächlich ist diese Annäherung so häufig, dass sie einen Namen hat : Mebi , Gibi und Tebi sind Mega, Giga bzw. Tera. Wenn Sie die Frage @WillManley nicht beantworten, haben Sie da einen fairen Punkt! ;-p
Mike Williamson
9

Wenn Sie sich strikt an die Frage halten, lautet der Python-Code (+ Pseudocode):

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

Wir haben zwei Möglichkeiten. Beide beinhalten den Import von OS-Modulen

1) importiere os als os.stat () Funktion gibt ein Objekt zurück, das so viele Header enthält, einschließlich der Erstellungszeit der Datei und der letzten Änderungszeit usw. Unter anderem gibt st_size () die genaue Größe der Datei an.

os.stat ("Dateiname"). st_size ()

2) os importieren Hier müssen wir den genauen Dateipfad (absoluten Pfad) angeben, keinen relativen Pfad.

os.path.getsize ("Pfad der Datei")

gunarevuri
quelle