ฉันจะตรวจสอบขนาดไฟล์ใน Python ได้อย่างไร?


757

ฉันกำลังเขียนสคริปต์ Python ใน Windows ฉันต้องการทำบางสิ่งตามขนาดของไฟล์ ตัวอย่างเช่นหากขนาดใหญ่กว่า 0 ฉันจะส่งอีเมลถึงใครบางคนหรือทำอย่างอื่นต่อไป

ฉันจะตรวจสอบขนาดไฟล์ได้อย่างไร


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

ขอบคุณ @Boris สำหรับคำตอบ Python ที่ทันสมัย ​​(v3.4 +) :)
mab

คำตอบ:


734

คุณจำเป็นต้องมีst_sizeทรัพย์สินของวัตถุที่ส่งกลับโดย os.statคุณสามารถทำได้โดยใช้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

หรือใช้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

เอาต์พุตอยู่ในหน่วยไบต์


2
หากมีสิ่งใดค่าสามารถส่งผ่านเป็นทวีคูณของขนาดบล็อกระบบไฟล์ (ตัวอย่างเช่น 4096 ไบต์) ดีใจที่ได้รับเป็นไบต์แทน
josch

1
@josch - ใช่นี่เป็นสิ่งที่ดีสำหรับ "size on disk" คุณสามารถคูณstat_result.st_blocksด้วยขนาดบล็อก แต่ฉันยังคงค้นหาวิธีรับโปรแกรมและข้ามแพลตฟอร์ม (ไม่ผ่านtune2fsฯลฯ )
Tomasz Gandor

1097

การใช้os.path.getsize:

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

เอาต์พุตอยู่ในหน่วยไบต์


124
หมายเหตุ: การดำเนินการos.path.getsizeเป็นเพียงreturn os.stat(filename).st_size
Wim

ดังนั้นจึงมีการสูญเสียประสิทธิภาพหนึ่งนาทีจากการใช้ os.path.getsize เมื่อเทียบกับ os.stat (ไฟล์) .st_size?
wordoforthewise

5
@ คำบอกเวลาวัดได้! ~ 150 ns ในคอมพิวเตอร์ของฉัน
Davidmh

@wordsforthewise นี้มีมากขึ้นของปัญหาถ้าคุณยังต้องการที่จะได้รับสิ่งอื่น ๆ ที่เกี่ยวกับไฟล์ (เวลาปรับเปลี่ยนชนิดของไฟล์เช่น) - os.statแล้วคุณอาจรวมทั้งได้รับมันทั้งหมดจากสายระบบเดียวผ่าน จากนั้นความแตกต่างอาจมีจำนวน microseconds :-) มากมาย
greggo

ถ้ามันถูกเรียกหลังจากสร้างไฟล์มันจะส่งคืน 0 @danben
alper

131

คำตอบอื่น ๆ ใช้งานได้กับไฟล์จริง แต่ถ้าคุณต้องการบางอย่างที่เหมาะกับ "วัตถุที่คล้ายไฟล์" ลองสิ่งนี้:

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

มันใช้งานได้กับไฟล์จริงและของ StringIO ในการทดสอบที่ จำกัด ของฉัน (Python 2.7.3.) "File เหมือนวัตถุ" API ไม่ได้จริงๆอินเตอร์เฟซที่เข้มงวดของหลักสูตร แต่เอกสาร APIแสดงให้เห็นว่าไฟล์เหมือนวัตถุควรสนับสนุนและseek()tell()

แก้ไข

ข้อแตกต่างระหว่างสิ่งนี้กับอีกอย่างos.stat()คือคุณสามารถstat()ทำไฟล์ได้แม้ว่าคุณจะไม่ได้รับอนุญาตให้อ่านมัน เห็นได้ชัดว่าวิธีการแสวงหา / บอกจะไม่ทำงานจนกว่าคุณจะได้รับอนุญาตให้อ่าน

แก้ไข 2

ตามคำแนะนำของ Jonathon นี่เป็นเวอร์ชั่นหวาดระแวง (รุ่นด้านบนออกจากตัวชี้ไฟล์ที่ท้ายไฟล์ดังนั้นหากคุณพยายามที่จะอ่านจากไฟล์คุณจะได้ 0 ไบต์กลับ!)

# 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
คุณไม่จำเป็นต้องนำเข้าosแทนที่จะเขียนf.seek(0, 2)เพื่อค้นหา 0 ไบต์จากจุดสิ้นสุด
cdosborn

2
และสำหรับบรรทัดสุดท้ายหากosไม่ได้ใช้:f.seek(old_file_position, 0)
luckydonald

48
หากคุณใช้ตัวอักษรจำนวนเต็มแทนที่จะเป็นตัวแปรที่มีชื่อคุณกำลังทรมานใครก็ตามที่ต้องรักษารหัสของคุณ osไม่มีเหตุผลที่น่าสนใจไม่ได้ที่จะนำเข้า
Mark E. Haase

ขอบคุณสำหรับการแก้ปัญหาที่ฉันได้ดำเนินการและมันทำงานได้ดี เพียงเพื่อยืนยันsizeเอาท์พุทเป็นไบต์?
Kedar.Aitawdekar

3
เห็นได้ชัดว่านี่เป็นความเสี่ยงอย่างน้อยขึ้นอยู่กับว่า Python ใช้งานอย่างไร#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)

ผลลัพธ์:

6.1 MB

5
this function will convert bytes to MB.... GB... etcไม่ถูกต้อง. ฟังก์ชั่นนี้จะแปลงไบต์เป็น MiB, GiB ฯลฯ ดูโพสต์นี้
moi

2
บรรทัดที่ 10 สามารถเปลี่ยนเป็นreturn f'{num:.1f} {x}'Python> = 3.5
Matt M.

53

การใช้pathlib( เพิ่มใน Python 3.4หรือ backport ที่มีในPyPI ):

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

นี่เป็นเพียงอินเทอร์เฟซรอบ ๆos.statแต่การใช้pathlibให้วิธีที่ง่ายในการเข้าถึงการดำเนินการอื่น ๆ ที่เกี่ยวข้องกับไฟล์


18

มีbitshiftเคล็ดลับที่ฉันใช้ถ้าฉันต้องการแปลงจากbytesหน่วยอื่น ๆ หากคุณทำการเปลี่ยนแปลงที่ถูกต้องโดย10คุณโดยทั่วไปแล้วจะเปลี่ยนตามคำสั่งซื้อ (หลายรายการ)

ตัวอย่าง: 5GB are 5368709120 bytes

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

9
สิ่งนี้ไม่ตอบคำถาม คำถามคือเกี่ยวกับการค้นหาขนาดของไฟล์ไม่ใช่เกี่ยวกับการจัดรูปแบบผลลัพธ์สำหรับการบริโภคของมนุษย์
Will Manley

1
ตัวเลขเหล่านี้ผิดและทำให้เกิดความสับสน 5GB คือ 5e9 ไบต์ นี่ควรจะเป็นการประมาณที่มนุษย์สามารถอ่านได้หรือไม่? คุณจะใช้อะไรแบบนี้ที่ไหน
Dre

1-bit => 2 ... 2-bits => 4 ... 3-bits => 8 ... 4-bits => 16 ... 5-bits => 32 ... 6-bits => 64 ... 7-bits => 128 ... 8-bits => 256 ... 9-bits => 512 ... 10-bits => 1024 ... 1024 ไบต์ 1024 คือ 1kB ... => 20 -bits => 1024 * 1024 = 1,048,576bytes ซึ่งเป็น 1024kB และ 1MB ... => 30-bits => 1024 * 1024 * 1024 = 1,073,741,824 ไบต์ซึ่งเท่ากับ 1,048,576 kB และ 1024MB และ 1GB …คุณสับสน สัญลักษณ์ทางวิทยาศาสตร์และตำแหน่งทศนิยมที่มีการแสดงเลขฐานสอง / ฐาน -2 ที่ใช้ในการคำนวณ 5x9 = 5 x 10 ^ 9 = 5,000,000,000
James 'Fluffy' Burton

3
พวกเขาไม่ได้สับสนอะไรเลย ... เขาเพิ่งได้รับการประมาณซึ่งเห็นได้ชัดเมื่อเขาพูดว่า "โดยทั่วไป" ประมาณ 2 ^ 10 10 ^ 3 ในความเป็นจริงการประมาณนี้เป็นเรื่องธรรมดามากที่มีชื่อ : Mebi , GibiและTebiเป็น Mega, Giga และ Tera ตามลำดับ เกี่ยวกับการไม่ตอบคำถาม @WillManley คุณมีจุดที่เหมาะสมแล้ว! ;-p
Mike Williamson

9

การยึดติดกับคำถามอย่างเคร่งครัดรหัส Python (+ pseudo-code) จะเป็น:

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

เรามีสองตัวเลือกทั้งสองรวมถึงการนำเข้าโมดูลระบบปฏิบัติการ

1) นำเข้าระบบปฏิบัติการเป็น os.stat () ฟังก์ชั่นส่งคืนวัตถุที่มีส่วนหัวจำนวนมากรวมถึงเวลาที่สร้างไฟล์และเวลาที่แก้ไขล่าสุด ฯลฯ ในหมู่พวกเขา st_size () ให้ขนาดที่แน่นอนของไฟล์

os.stat ( "ชื่อไฟล์"). st_size ()

2) การนำเข้าระบบปฏิบัติการในสิ่งนี้เราจะต้องให้เส้นทางไฟล์ที่แน่นอน (เส้นทางที่แน่นอน) ไม่ใช่เส้นทางสัมพัทธ์

os.path.getsize ("เส้นทางของไฟล์")

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.