Bagaimana saya bisa memeriksa ukuran file dengan Python?

757

Saya menulis skrip Python di Windows. Saya ingin melakukan sesuatu berdasarkan ukuran file. Misalnya, jika ukurannya lebih besar dari 0, saya akan mengirim email kepada seseorang, jika tidak melanjutkan ke hal lain.

Bagaimana saya memeriksa ukuran file?

5YrsLaterDBA
sumber
2
Path('./doc.txt').stat().st_size
Boris
Terima kasih @Boris untuk jawaban Python (v3.4 +) modern :)
mab

Jawaban:

735

Anda memerlukan st_sizeproperti objek yang dikembalikan olehos.stat . Anda bisa mendapatkannya dengan menggunakan 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

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

Output dalam byte.

Adam Rosenfield
sumber
2
Jika ada, nilainya dapat diteruskan sebagai kelipatan dari ukuran blok sistem file (misalnya, 4096 byte). Dengan senang hati, itu diberikan sebagai byte.
josch
1
@ josch - ya, ini bagus, untuk "ukuran pada disk" Anda dapat mengalikan stat_result.st_blocksdengan ukuran blok, tapi saya masih mencari cara untuk mendapatkannya secara terprogram dan lintas-platform (tidak melalui tune2fsdll.)
Tomasz Gandor
1098

Menggunakan os.path.getsize:

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

Outputnya dalam byte.

danben
sumber
124
Catatan: implementasi os.path.getsizesederhanareturn os.stat(filename).st_size
wim
Jadi apakah ada kehilangan kinerja sebentar dari menggunakan os.path.getsize sebagai lawan dari os.stat (file) .st_size?
kata
5
@wordsselalu mengukurnya! ~ 150 ns di komputer saya.
Davidmh
@wordssudah ini lebih merupakan masalah jika Anda juga ingin mendapatkan hal-hal lain tentang file (waktu modifikasi, jenis file, misalnya) - maka Anda mungkin mendapatkan semuanya dari satu panggilan sistem melalui os.stat. Maka perbedaannya dapat mencapai sejumlah besar mikrodetik :-)
greggo
Jika dipanggil tepat setelah file dibuat, ia mengembalikan 0 @ danben
alper
131

Jawaban lain berfungsi untuk file nyata, tetapi jika Anda memerlukan sesuatu yang berfungsi untuk "objek seperti file", coba ini:

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

Ini berfungsi untuk file nyata dan StringIO, dalam pengujian terbatas saya. (Python 2.7.3.) API "objek seperti file" sebenarnya bukan antarmuka yang ketat, tetapi dokumentasi API menunjukkan bahwa objek seperti file harus mendukung seek()dan tell().

Edit

Perbedaan lain antara ini dan os.stat()Anda dapat stat()file bahkan jika Anda tidak memiliki izin untuk membacanya. Jelas pendekatan mencari / memberi tahu tidak akan berhasil kecuali jika Anda telah membaca izin.

Edit 2

Atas saran Jonathon, inilah versi paranoid. (Versi di atas meninggalkan penunjuk file di akhir file, jadi jika Anda mencoba membaca dari file, Anda akan mendapatkan nol byte kembali!)

# 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
sumber
8
Anda tidak perlu mengimpor os, alih-alih menulis f.seek(0, 2)untuk mencari 0 byte dari akhir.
cdosborn
2
Dan untuk baris terakhir, jika ostidak digunakan:f.seek(old_file_position, 0)
luckydonald
48
Jika Anda menggunakan bilangan bulat integer alih-alih variabel bernama, Anda menyiksa siapa pun yang harus menjaga kode Anda. Tidak ada alasan kuat untuk tidak mengimpor os.
Mark E. Haase
Terima kasih atas solusinya, saya telah menerapkan dan berfungsi dengan baik. Hanya untuk mengonfirmasi, sizeoutput dalam byte?
Kedar.Aitawdekar
3
Tampaknya ini setidaknya sedikit berisiko, tergantung pada bagaimana Python mengimplementasikan #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)

Hasil:

6.1 MB
Rajiv Sharma
sumber
5
this function will convert bytes to MB.... GB... etcSalah. Fungsi ini akan mengkonversi byte ke MiB, GiB, dll. Lihat posting ini .
moi
2
Baris 10 dapat diubah ke return f'{num:.1f} {x}'dalam Python> = 3.5.
Matt M.
53

Menggunakan pathlib( ditambahkan dengan Python 3.4 atau backport yang tersedia di PyPI ):

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

Ini benar-benar hanya antarmuka di sekitar os.stat, tetapi menggunakan pathlibmenyediakan cara mudah untuk mengakses operasi terkait file lainnya.

pumazi
sumber
18

Ada bitshifttrik yang saya gunakan jika saya ingin mengkonversi dari byteske unit lain. Jika Anda melakukan pergeseran dengan benar 10pada dasarnya Anda menggesernya dengan perintah (banyak)

Contoh: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)
pengguna1767754
sumber
9
Ini tidak menjawab pertanyaan. Pertanyaannya adalah tentang menemukan ukuran file, bukan tentang memformat hasil untuk konsumsi manusia.
Will Manley
1
Angka-angka ini salah dan karenanya membingungkan. 5GB adalah 5e9 byte. Apakah ini seharusnya semacam pendekatan yang bisa dibaca manusia? Di mana Anda bahkan akan menggunakan sesuatu seperti ini?
Dre
1-bit => 2 ... 2-bit => 4 ... 3-bit => 8 ... 4-bit => 16 ... 5-bit => 32 ... 6-bit => 64 ... 7-bit => 128 ... 8-bits => 256 ... 9-bits => 512 ... 10-bits => 1024 ... 1024 bytes adalah 1kB ... => 20 -bits => 1024 * 1024 = 1.048.576bytes, yaitu 1024kB, dan 1MB ... => 30-bit => 1024 * 1024 * 1024 = 1.073.741.824 byte, yaitu 1.048.576 kB, dan 1024MB, dan 1GB ... Anda bingung notasi ilmiah dan tempat desimal dengan representasi biner / basis-2 yang digunakan dalam komputasi. 5x9 = 5 x 10 ^ 9 = 5.000.000.000
James 'Fluffy' Burton
3
Guys, dia tidak bingung apa - apa ... dia hanya memberikan perkiraan, yang terbukti ketika dia mengatakan "pada dasarnya". 2 ^ 10 kira-kira. 10 ^ 3. Bahkan, perkiraan ini sangat umum sehingga memiliki nama : Mebi , Gibi , dan Tebi masing-masing adalah Mega, Giga, dan Tera. Mengenai tidak menjawab pertanyaan, @ WillManley, Anda memiliki titik adil di sana! ;-p
Mike Williamson
9

Berpegang teguh pada pertanyaan, kode Python (+ pseudo-code) adalah:

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

kami memiliki dua opsi. Keduanya termasuk mengimpor modul os

1) import os as fungsi os.stat () mengembalikan objek yang berisi begitu banyak header termasuk waktu pembuatan file dan waktu modifikasi terakhir dll. Di antaranya st_size () memberikan ukuran file yang tepat.

os.stat ("nama file"). st_size ()

2) import os. Dalam hal ini, kita harus menyediakan path file yang tepat (path absolut), bukan path relatif.

os.path.getsize ("path of file")

gunarevuri
sumber