Get actual disk space of a file

Question:

How do I get the actual filesize on disk in python? (the actual size it takes on the harddrive).

Asked By: Alex

||

Answers:

I’m not certain if this is size on disk, or the logical size:

import os
filename = "/home/tzhx/stuff.wev"
size = os.path.getsize(filename)

If it’s not the droid your looking for, you can round it up by dividing by cluster size (as float), then using ceil, then multiplying.

Answered By: TZHX
st = os.stat(…)
du = st.st_blocks * st.st_blksize
Answered By: ephemient

UNIX only:

import os
from collections import namedtuple

_ntuple_diskusage = namedtuple('usage', 'total used free')

def disk_usage(path):
    """Return disk usage statistics about the given path.

    Returned valus is a named tuple with attributes 'total', 'used' and
    'free', which are the amount of total, used and free space, in bytes.
    """
    st = os.statvfs(path)
    free = st.f_bavail * st.f_frsize
    total = st.f_blocks * st.f_frsize
    used = (st.f_blocks - st.f_bfree) * st.f_frsize
    return _ntuple_diskusage(total, used, free)

Usage:

>>> disk_usage('/')
usage(total=21378641920, used=7650934784, free=12641718272)
>>>

Edit 1 – also for Windows: https://code.activestate.com/recipes/577972-disk-usage/?in=user-4178764

Edit 2 – this is also available in Python 3.3+: https://docs.python.org/3/library/shutil.html#shutil.disk_usage

Answered By: Giampaolo Rodolà

Update 2021-03-26: Previously, my answer rounded the logical size of the file up to be an integer multiple of the block size. This approach only works if the file is stored in a continuous sequence of blocks on disk (or if all the blocks are full except for one). Since this is a special case (though common for small files), I have updated my answer to make it more generally correct. However, note that unfortunately the statvfs method and the st_blocks value may not be available on some system (e.g., Windows 10).

Call os.stat(filename).st_blocks to get the number of blocks in the file.

Call os.statvfs(filename).f_bsize to get the filesystem block size.

Then compute the correct size on disk, as follows:

num_blocks = os.stat(filename).st_blocks
block_size = os.statvfs(filename).f_bsize
sizeOnDisk = num_blocks*block_size
Answered By: hft

To get the disk usage for a given file/folder, you can do the following:

import os

def disk_usage(path):
    """Return cumulative number of bytes for a given path."""
    # get total usage of current path
    total = os.path.getsize(path)
    # if path is dir, collect children
    if os.path.isdir(path):
        for file_name in os.listdir(path):
            child = os.path.join(path, file_name)
            # recursively get byte use for children
            total += disk_usage(child)
    return total

The function recursively collects byte usage for files nested within a given path, and returns the cumulative use for the entire path.
You could also add a print "{path}: {bytes}".format(path, total) in there if you want the information for each file to print.

Answered By: Jared Wilber

Here is the correct way to get a file’s size on disk, on platforms where st_blocks is set:

import os

def size_on_disk(path):
    st = os.stat(path)
    return st.st_blocks * 512

Other answers that indicate to multiply by os.stat(path).st_blksize or os.vfsstat(path).f_bsize are simply incorrect.

The Python documentation for os.stat_result.st_blocks very clearly states:

st_blocks
Number of 512-byte blocks allocated for file. This may be smaller than st_size/512 when the file has holes.

Furthermore, the stat(2) man page says the same thing:

blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
Answered By: Jonathon Reinhart

Practically 12 years and no answer on how to do this in windows…

Here’s how to find the ‘Size on disk’ in windows via ctypes;

import ctypes
def GetSizeOnDisk(path):
    '''https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getcompressedfilesizew'''
    filesizehigh = ctypes.c_ulonglong(0) # not sure about this... something about files >4gb
    return ctypes.windll.kernel32.GetCompressedFileSizeW(ctypes.c_wchar_p(path),ctypes.pointer(filesizehigh))

'''
>>> os.stat(somecompressedorofflinefile).st_size
943141
>>> GetSizeOnDisk(somecompressedorofflinefile)
671744
>>>
'''
Answered By: J_K
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.