Làm cách nào để kiểm tra kích thước tệp trong Python?


757

Tôi đang viết một kịch bản Python trong Windows. Tôi muốn làm một cái gì đó dựa trên kích thước tập tin. Ví dụ: nếu kích thước lớn hơn 0, tôi sẽ gửi email cho ai đó, nếu không thì tiếp tục những việc khác.

Làm cách nào để kiểm tra kích thước tệp?


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

Cảm ơn @Boris về câu trả lời Python (v3.4 +) hiện đại :)
mab

Câu trả lời:


735

Bạn cần st_sizetài sản của đối tượng trả vềos.stat . Bạn có thể lấy nó bằng cách sử dụng 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

hoặc sử dụng 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

Đầu ra được tính bằng byte.


2
Nếu bất cứ điều gì, giá trị có thể được chuyển qua dưới dạng bội số của kích thước khối hệ thống tệp (ví dụ 4096 byte). Rất vui, nó được đưa ra dưới dạng byte thay thế.
josch

1
@josch - vâng, điều này thật tuyệt, với "kích thước trên đĩa" bạn có thể nhân stat_result.st_blocksvới kích thước khối, nhưng tôi vẫn đang tìm cách lấy nó theo lập trình và đa nền tảng (không thông qua tune2fsv.v.)
Tomasz Gandor

1098

Sử dụng os.path.getsize:

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

Đầu ra được tính bằng byte.


124
Lưu ý: việc thực hiện os.path.getsizechỉ đơn giản làreturn os.stat(filename).st_size
wim

Vì vậy, có mất hiệu suất phút khi sử dụng os.path.getsize trái ngược với os.stat (tệp) .st_size không?
lời giới thiệu

5
@wordsforthewise đo nó! ~ 150 ns trong máy tính của tôi.
Davidmh

@wordsforthewise đây là một vấn đề nếu bạn cũng muốn nhận được những thứ khác về tệp (thời gian sửa đổi, loại tệp, v.v.) - thì bạn cũng có thể nhận được tất cả từ một cuộc gọi hệ thống duy nhất thông qua os.stat. Sau đó, sự khác biệt có thể xảy ra với số lượng đáng kể micro giây :-)
greggo

Nếu nó được gọi ngay sau khi một tập tin được tạo ra nó trả về 0 @danben
Alper

131

Các câu trả lời khác hoạt động cho các tệp thực, nhưng nếu bạn cần một cái gì đó hoạt động cho "các đối tượng giống như tệp", hãy thử điều này:

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

Nó hoạt động cho các tệp thực và StringIO, trong thử nghiệm giới hạn của tôi. (Python 2.7.3.) Tất nhiên, API "đối tượng giống như tệp" không thực sự là một giao diện nghiêm ngặt, nhưng tài liệu API cho thấy các đối tượng giống như tệp nên hỗ trợ seek()tell().

Biên tập

Một điểm khác biệt giữa điều này và os.stat()là bạn có thể tạo stat()một tập tin ngay cả khi bạn không có quyền đọc nó. Rõ ràng phương pháp tìm kiếm / nói sẽ không hiệu quả trừ khi bạn có quyền đọc.

Chỉnh sửa 2

Theo đề nghị của Jonathon, đây là phiên bản hoang tưởng. (Phiên bản ở trên để lại con trỏ tệp ở cuối tệp, vì vậy nếu bạn cố đọc từ tệp, bạn sẽ nhận được 0 byte trở lại!)

# 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
Bạn không cần nhập os, thay vào đó hãy viết f.seek(0, 2)để tìm kiếm 0 byte từ cuối.
cdosborn

2
Và cho dòng cuối cùng, nếu oskhông được sử dụng:f.seek(old_file_position, 0)
luckydonald

48
Nếu bạn sử dụng các số nguyên thay vì các biến được đặt tên, bạn đang tra tấn bất kỳ ai phải duy trì mã của mình. Không có lý do thuyết phục để không nhập khẩu os.
Đánh dấu E. Haase

Cảm ơn giải pháp, tôi đã thực hiện và nó hoạt động tốt. Chỉ cần xác nhận, sizeđầu ra là byte?
Kedar.Aitawdekar

3
Rõ ràng điều này ít nhất là một chút rủi ro, tùy thuộc vào cách Python thực hiện #seek(): wiki.sei.cmu.edu/confluence/display/c/iêu
Autumnsault 17/8/18

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)

Kết quả:

6.1 MB

5
this function will convert bytes to MB.... GB... etcSai lầm. Hàm này sẽ chuyển đổi byte thành MiB, GiB, v.v ... Xem bài đăng này .
moi

2
Dòng 10 có thể được thay đổi thành return f'{num:.1f} {x}'Python> = 3.5.
Matt M.

53

Sử dụng pathlib( được thêm vào Python 3.4 hoặc backport có sẵn trên PyPI ):

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

Đây thực sự chỉ là một giao diện xung quanh os.stat, nhưng việc sử dụng pathlibcung cấp một cách dễ dàng để truy cập các hoạt động liên quan đến tệp khác.


18

Có một bitshiftmẹo tôi sử dụng nếu tôi muốn chuyển đổi từ bytesbất kỳ đơn vị nào khác. Nếu bạn thực hiện một ca đúng bởi 10bạn về cơ bản thay đổi nó theo một đơn đặt hàng (nhiều).

Thí dụ: 5GB are 5368709120 bytes

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

9
Điều này không trả lời câu hỏi. Câu hỏi là về việc tìm kích thước của một tệp chứ không phải về định dạng kết quả cho mức tiêu thụ của con người.
Will Manley

1
Những con số này là sai và do đó khó hiểu. 5GB là 5e9 byte. Đây có phải là một loại gần đúng có thể đọc được của con người? Bạn thậm chí sẽ sử dụng một cái gì đó như thế này?
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 là 1kB ... => 20 -bits => 1024 * 1024 = 1.048.576byte, là 1024kB và 1MB ... => 30-bit => 1024 * 1024 * 1024 = 1.073.741.824 byte, là 1.048.576 kB và 1024 MB và 1GB. ký hiệu khoa học và vị trí thập phân với biểu diễn nhị phân / cơ sở 2 được sử dụng trong điện toán. 5x9 = 5 x 10 ^ 9 = 5.000.000.000
James 'Fluffy' Burton

3
Các bạn, anh ta đã không nhầm lẫn bất cứ điều gì ... anh ta chỉ đưa ra một xấp xỉ, điều này thể hiện rõ khi anh ta nói "về cơ bản". 2 ^ 10 là khoảng. 10 ^ 3. Trong thực tế, xấp xỉ này là rất phổ biến mà nó có một cái tên : Mebi , GIBI , và Tebi là Mega, Giga, và Tera, tương ứng. Về việc không trả lời câu hỏi, @WillManley, bạn có một điểm công bằng ở đó! ;-p
Mike Williamson

9

Bám sát vào câu hỏi, mã Python (+ mã giả) sẽ là:

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

chúng tôi có hai tùy chọn Cả hai bao gồm nhập mô-đun os

1) nhập hàm os dưới dạng os.stat () trả về một đối tượng chứa rất nhiều tiêu đề bao gồm thời gian tạo tệp và thời gian sửa đổi lần cuối, v.v. trong số đó st_size () đưa ra kích thước chính xác của tệp.

os.stat ("tên tệp"). st_size ()

2) nhập os Trong trường hợp này, chúng tôi phải cung cấp đường dẫn tệp chính xác (đường dẫn tuyệt đối), không phải là đường dẫn tương đối.

os.path.getsize ("đường dẫn của tệp")

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.