Jak mogę sprawdzić rozmiar pliku w Pythonie?


757

Piszę skrypt w języku Python w systemie Windows. Chcę zrobić coś na podstawie rozmiaru pliku. Na przykład, jeśli rozmiar jest większy niż 0, wyślę do kogoś wiadomość e-mail, w przeciwnym razie przejdź do innych rzeczy.

Jak sprawdzić rozmiar pliku?


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

Dzięki @ Boris za nowoczesną odpowiedź na Python (v3.4 +) :)
— mab

Odpowiedzi:


734

Potrzebujesz st_sizewłaściwości obiektu zwróconego przezos.stat . Możesz go uzyskać za pomocą 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

lub używając 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

Dane wyjściowe są w bajtach.


2
Jeśli już, wartość można przekazać jako wielokrotność wielkości bloku systemu plików (na przykład 4096 bajtów). Chętnie zamiast tego jest podawany jako bajty.
— josch

1
@josch - tak, to fajnie, bo „rozmiar na dysku” można pomnożyć stat_result.st_blocksprzez rozmiar bloku, ale wciąż szukam, jak uzyskać go programowo i na różnych platformach (nie za pośrednictwem tune2fsitp.)
— Tomasz Gandor

1097

Używanie os.path.getsize:

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

Dane wyjściowe są w bajtach.


124
Uwaga: wdrożenie os.path.getsizejest po prostureturn os.stat(filename).st_size
— wim

Czy jest więc niewielka utrata wydajności przy użyciu os.path.getsize w przeciwieństwie do os.stat (plik) .st_size?
— słowa

5
@wordforthewise zmierzyć to! ~ 150 ns na moim komputerze.
— Davidmh

@ słowa, w przeciwnym razie jest to większy problem, jeśli chcesz uzyskać inne informacje na temat pliku (czas modyfikacji, typ pliku, np.) - wtedy równie dobrze możesz uzyskać wszystko z jednego wywołania systemowego za pośrednictwem os.stat. Różnica może wtedy
— spaść

Jeśli zostanie wywołany bezpośrednio po utworzeniu pliku, zwraca 0 @danben
— alper

131

Inne odpowiedzi działają dla prawdziwych plików, ale jeśli potrzebujesz czegoś, co działa dla „obiektów podobnych do plików”, spróbuj tego:

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

W moich ograniczonych testach działa dla prawdziwych plików i StringIO. (Python 2.7.3.) Interfejs API „obiektopodobny” nie jest tak naprawdę rygorystycznym interfejsem, ale dokumentacja API sugeruje, że obiekty podobne do plików powinny obsługiwać seek()i tell().

Edytować

Kolejna różnica między tym a os.stat()tym, że możesz stat()utworzyć plik, nawet jeśli nie masz pozwolenia na jego odczytanie. Oczywiście podejście „szukaj / mów” nie będzie działać, chyba że masz uprawnienia do odczytu.

Edytuj 2

Według sugestii Jonathona, oto wersja paranoiczna. (Powyższa wersja pozostawia wskaźnik pliku na końcu pliku, więc jeśli spróbujesz odczytać z pliku, otrzymasz z powrotem zero bajtów!)

# 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
Nie musisz importować os, zamiast tego napisz, f.seek(0, 2)aby wyszukać 0 bajtów od końca.
— cdosborn

2
I dla ostatniego wiersza, jeśli osnie jest używany:f.seek(old_file_position, 0)
— luckydonald

48
Jeśli używasz literałów całkowitych zamiast nazwanych zmiennych, torturujesz każdego, kto musi utrzymywać twój kod. Nie ma ważnego powodu, aby nie importować os.
— Mark E. Haase,

Dzięki za rozwiązanie, które zaimplementowałem i działa dobrze. Żeby tylko potwierdzić, sizewyjście jest w bajtach?
— Kedar.Aitawdekar

3
Najwyraźniej jest to co najmniej trochę ryzykowne, w zależności od tego, jak Python implementuje #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)

Wynik:

6.1 MB

5
this function will convert bytes to MB.... GB... etcŹle. Ta funkcja konwertuje bajty na MiB, GiB itp. Zobacz ten post .
— moi

2
Wiersz 10 można zmienić na return f'{num:.1f} {x}'w Pythonie> = 3.5.
— Matt M.

53

Za pomocą pathlib( dodany w Python 3.4 lub backport dostępny w PyPI ):

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

W rzeczywistości jest to tylko interfejs os.stat, ale korzystanie z niego pathlibzapewnia łatwy dostęp do innych operacji związanych z plikami.


18

Jest pewien bitshiftpodstęp, którego używam, jeśli chcę przekonwertować z bytesdowolnej innej jednostki. Jeśli wykonasz właściwą zmianę, 10po prostu przesuń ją o kolejność (wielokrotność).

Przykład: 5GB are 5368709120 bytes

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

9
To nie odpowiada na pytanie. Pytanie dotyczy znalezienia rozmiaru pliku, a nie sformatowania wyniku do spożycia przez ludzi.
— Will Manley,

1
Te liczby są błędne, a zatem mylące. 5 GB to 5e9 bajtów. Czy to ma być jakieś czytelne dla człowieka przybliżenie? Gdzie w ogóle użyłbyś czegoś takiego?
— Dre

1-bit => 2 ... 2-bity => 4 ... 3-bity => 8 ... 4-bity => 16 ... 5-bitów => 32 ... 6-bit = 64 ... 7-bitów => 128 ... 8-bitów => 256 ... 9-bitów => 512 ... 10-bitów => 1024 ... 1024 bajtów to 1kB ... => 20 -bity => 1024 * 1024 = 1 048 576 bajtów, czyli 1024 kB i 1 MB ... => 30-bitów => 1024 * 1024 * 1024 = 1 073 741 824 bajtów, co stanowi 1 048 576 kB i 1024 MB, a 1 GB… Myliłeś się notacja naukowa i miejsca dziesiętne z reprezentacją binarną / base-2 używaną w obliczeniach. 5x9 = 5 x 10 ^ 9 = 5 000 000 000
— James „Fluffy” Burton

3
Chłopaki, niczego nie pomylił ... podał tylko przybliżenie, co jest oczywiste, kiedy mówi „w zasadzie”. 2 ^ 10 to ok. 10 ^ 3. W rzeczywistości to przybliżenie jest tak powszechne, że ma nazwę : Mebi , Gibi i Tebi to odpowiednio Mega, Giga i Tera. Jeśli chodzi o brak odpowiedzi na pytanie, @WillManley, masz rację! ;-p
— Mike Williamson

9

Ściśle trzymając się pytania, kod Pythona (+ pseudo-kod) to:

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

mamy dwie opcje Obie obejmują importowanie modułu OS

1) import os as funkcja os.stat () zwraca obiekt, który zawiera tak wiele nagłówków, w tym czas utworzenia pliku i czas ostatniej modyfikacji itp. Pośród nich st_size () podaje dokładny rozmiar pliku.

os.stat („nazwa pliku”). st_size ()

2) import os W tym celu musimy podać dokładną ścieżkę do pliku (ścieżkę bezwzględną), a nie ścieżkę względną.

os.path.getsize („ścieżka pliku”)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.