1196

How do I get the size of a file in Python?

0

11 Answers 11

1541

Use os.path.getsize:

>>> import os
>>> os.path.getsize("/path/to/file.mp3")
2071611

The output is in bytes.

5
  • 193
    Note: the implementation of os.path.getsize is simply return os.stat(filename).st_size
    – wim
    Commented Mar 21, 2013 at 11:20
  • 1
    So is there a minute performance loss from using os.path.getsize as opposed to os.stat(file).st_size? Commented May 18, 2015 at 1:45
  • 12
    @wordsforthewise measure it! ~150 ns in my computer.
    – Davidmh
    Commented Jul 15, 2015 at 11:24
  • 8
    @wordsforthewise this is more of an issue if you also want to get other things about the file (modification time, type of file, e.g.) -- then you might as well get it all from a single system call via os.stat. Then the difference could run into a substantial number of microseconds :-)
    – greggo
    Commented Dec 21, 2019 at 18:24
  • Another advantage of directly using os.stat() is, that it accepts filenames relative to a directory file descriptor dir_fd as in os.stat(relname, dir_fd=mydirfd).st_size, while os.path.getsize() does not. When parsing through directory trees, dir_fd can be a large advantage.
    – Kai Petzke
    Commented Nov 6, 2023 at 19:07
1091

You need the st_size property of the object returned by os.stat. You can get it by either using 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

or using 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 is in bytes.

2
  • 3
    @josch - yes, this is nice, for the "size on disk" you can multiply stat_result.st_blocks by the block size, but I'm still searching how to get it programmatically and cross-platform (not via tune2fs etc.) Commented Apr 22, 2016 at 20:56
  • 2
    @TomaszGandor now st_blocks is defined as "Number of 512-byte blocks allocated for file", so you don't have to get the block size. Commented Apr 14, 2023 at 8:45
152

The other answers work for real files, but if you need something that works for "file-like objects" (e.g. a StringIO), try this:

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

Caveat #1:

The "file-like object" API isn't a rigorous interface but the API documentation suggests that file-like objects should support seek() and tell(), but you should verify this yourself for whatever class you're using.

Caveat #2:

This assumes that the current file position is at the beginning of the file. E.g. if you had already read N bytes from an M-byte file, then this technique would report the size as (M-N). If you don't care about file position at all, you could simplify the 3 lines above to just size = f.seek(0, os.SEEK_END).

Caveat #3:

One important difference between this and os.stat() is that you can stat() a file even if you don't have permission to read it. Obviously the seek() approach won't work unless you have read permission.

6
  • 2
    And for the last line, if os isn't used: f.seek(old_file_position, 0) Commented Dec 2, 2015 at 15:11
  • 71
    If you use integer literals instead of named variables, you are torturing anybody that has to maintain your code. There's no compelling reason not to import os. Commented Dec 2, 2015 at 16:25
  • 5
    Apparently this is at least a little risky, depending on how Python implements #seek(): wiki.sei.cmu.edu/confluence/display/c/…
    – Translunar
    Commented Aug 17, 2018 at 20:35
  • 1
    f.seek(0, os.SEEK_END) returns the number of bytes advanced to EOF. Wouldn't this be the same value returned with f.tell()? Commented Dec 23, 2024 at 18:16
  • 1
    Great point @ErikAnderson. I cleaned up my answer to take advantage of that fact. Commented Jan 2 at 18:07
112
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)

Result:

6.1 MB
3
  • 5
    Line 10 can be changed to return f'{num:.1f} {x}' in Python >= 3.5. Commented Jun 7, 2018 at 23:40
  • thank you Matt M., slight update, line 10 can be changed to return f'{num}{unit}' if unit == 'bytes' else f'{num:.1f}{unit}' in Python >= 3.5
    – MZA
    Commented Aug 3, 2020 at 15:05
  • file_info = os.stat(file_path).st_size Commented Mar 30, 2023 at 16:26
69

Using pathlib (added in Python 3.4 or a backport available on PyPI):

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

This is really only an interface around os.stat, but using pathlib provides an easy way to access other file related operations.

30

There is a bitshift trick I use if I want to to convert from bytes to any other unit. If you do a right shift by 10 you basically shift it by an order (multiple).

Example: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)
4
  • 16
    This doesn't answer the question. The question is about finding the size of a file, not about formatting the result for human consumption. Commented Apr 9, 2018 at 12:44
  • 2
    These numbers are wrong and thus confusing. 5GB is 5e9 bytes. Is this supposed to be some sort of human-readable approximation? Where would you even use something like this?
    – Dre
    Commented Aug 14, 2018 at 0:29
  • 4
    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 bytes is 1kB ... => 20-bits => 1024 * 1024 = 1,048,576bytes, which is 1024kB, and 1MB... => 30-bits => 1024 * 1024 * 1024 = 1,073,741,824 bytes, which is 1,048,576 kB, and 1024MB, and 1GB … You have confused scientific notation and decimal places with the binary/base-2 representation used in computing. 5x9 = 5 x 10^9 = 5,000,000,000 Commented Sep 12, 2018 at 15:33
  • 7
    Guys, he hasn't confused anything... he's just given an approximation, which is evident when he says "basically". 2^10 is approx. 10^3. In fact, this approximation is so common that it has a name: Mebi, Gibi, and Tebi are Mega, Giga, and Tera, respectively. Regarding not answering the question, @WillManley , you have a fair point there! ;-p Commented Oct 2, 2018 at 23:36
18

we have two options Both include importing os module

1)

import os
os.stat("/path/to/file").st_size

as os.stat() function returns an object which contains so many headers including file created time and last modified time etc.. among them st_size gives the exact size of the file. File path can be either absolute or relative.

2) In this, we have to provide the exact file path, File path can be either relative or absolute.

import os
os.path.getsize("path of file")
1
  • 1
    os.path.getsize works with a relative path
    – rachid
    Commented Nov 29, 2020 at 17:10
9

Strictly sticking to the question, the Python code (+ pseudo-code) would be:

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>
0

You can use the stat() method from the os module. You can provide it with a path in the form of a string, bytes or even a PathLike object. It works with file descriptors as well.

import os

res = os.stat(filename)

res.st_size # this variable contains the size of the file in bytes
1
  • Duplicate answer
    – Akaisteph7
    Commented Nov 11, 2024 at 20:30
0

Here's another self-explanatory example. With this, bytes will be converted into MBs, GBs, or TBs automatically.

from pathlib import Path
from psutil._common import bytes2human

def get_readable_filesize(text_file: Path):
    return bytes2human(text_file.stat().st_size)

if __name__ == '__main__':
    current_file = Path(__file__).parent.resolve()
    print(get_readable_filesize(current_file / 'file.txt'))
-3
#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 ....

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.