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.
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.)
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)
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?
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.0def 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)
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ść).
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>
#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 MBif fsize.st_size <10000000:
process it ....
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ą.
Path('./doc.txt').stat().st_size
Odpowiedzi:
Potrzebujesz
st_size
właściwości obiektu zwróconego przezos.stat
. Możesz go uzyskać za pomocąpathlib
(Python 3.4+):lub używając
os.stat
:Dane wyjściowe są w bajtach.
źródło
stat_result.st_blocks
przez rozmiar bloku, ale wciąż szukam, jak uzyskać go programowo i na różnych platformach (nie za pośrednictwemtune2fs
itp.)Używanie
os.path.getsize
:Dane wyjściowe są w bajtach.
źródło
os.path.getsize
jest po prostureturn os.stat(filename).st_size
os.stat
. Różnica może wtedyInne 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:
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()
itell()
.Edytować
Kolejna różnica między tym a
os.stat()
tym, że możeszstat()
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!)
źródło
os
, zamiast tego napisz,f.seek(0, 2)
aby wyszukać 0 bajtów od końca.os
nie jest używany:f.seek(old_file_position, 0)
os
.size
wyjście jest w bajtach?#seek()
: wiki.sei.cmu.edu/confluence/display/c/…Wynik:
źródło
this function will convert bytes to MB.... GB... etc
Źle. Ta funkcja konwertuje bajty na MiB, GiB itp. Zobacz ten post .return f'{num:.1f} {x}'
w Pythonie> = 3.5.Za pomocą
pathlib
( dodany w Python 3.4 lub backport dostępny w PyPI ):W rzeczywistości jest to tylko interfejs
os.stat
, ale korzystanie z niegopathlib
zapewnia łatwy dostęp do innych operacji związanych z plikami.źródło
Jest pewien
bitshift
podstęp, którego używam, jeśli chcę przekonwertować zbytes
dowolnej innej jednostki. Jeśli wykonasz właściwą zmianę,10
po prostu przesuń ją o kolejność (wielokrotność).źródło
Ściśle trzymając się pytania, kod Pythona (+ pseudo-kod) to:
źródło
źródło
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”)
źródło