Cross-platform space remaining on volume using python

44,192

Solution 1

import ctypes
import os
import platform
import sys

def get_free_space_mb(dirname):
    """Return folder/drive free space (in megabytes)."""
    if platform.system() == 'Windows':
        free_bytes = ctypes.c_ulonglong(0)
        ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(dirname), None, None, ctypes.pointer(free_bytes))
        return free_bytes.value / 1024 / 1024
    else:
        st = os.statvfs(dirname)
        return st.f_bavail * st.f_frsize / 1024 / 1024

Note that you must pass a directory name for GetDiskFreeSpaceEx() to work (statvfs() works on both files and directories). You can get a directory name from a file with os.path.dirname().

Also see the documentation for os.statvfs() and GetDiskFreeSpaceEx.

Solution 2

Install psutil using pip install psutil. Then you can get the amount of free space in bytes using:

import psutil
print(psutil.disk_usage(".").free)

Solution 3

You could use the wmi module for windows and os.statvfs for unix

for window

import wmi

c = wmi.WMI ()
for d in c.Win32_LogicalDisk():
    print( d.Caption, d.FreeSpace, d.Size, d.DriveType)

for unix or linux

from os import statvfs

statvfs(path)

Solution 4

If you're running python3:

Using shutil.disk_usage()with os.path.realpath('/') name-regularization works:

from os import path
from shutil import disk_usage

print([i / 1000000 for i in disk_usage(path.realpath('/'))])

Or

total_bytes, used_bytes, free_bytes = disk_usage(path.realpath('D:\\Users\\phannypack'))

print(total_bytes / 1000000) # for Mb
print(used_bytes / 1000000)
print(free_bytes / 1000000)

giving you the total, used, & free space in MB.

Solution 5

If you dont like to add another dependency you can for windows use ctypes to call the win32 function call directly.

import ctypes

free_bytes = ctypes.c_ulonglong(0)

ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(u'c:\\'), None, None, ctypes.pointer(free_bytes))

if free_bytes.value == 0:
   print 'dont panic'
Share:
44,192

Related videos on Youtube

Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I need a way to determine the space remaining on a disk volume using python on linux, Windows and OS X. I'm currently parsing the output of the various system calls (df, dir) to accomplish this - is there a better way?

  • jfs
    jfs over 15 years
    os.statvfs() doesn't work on Windows (Python 2.5.2 -- current production version).
  • jfs
    jfs about 14 years
    .f_bfree is total number of free blocks in the file system. It should be multiplied by .f_bsize to get number of bytes.
  • Dennis Bliefernicht
    Dennis Bliefernicht over 12 years
    At least on OS X Lion / Python 2.7 I noticed that multiplying by .f_bsize gives a much too large value as f_bsize is the preferred block size while .f_frsize is the fundamental block size and gives the correct value. On my linux test system both values are identical and thus .f_frsize should work all the time.
  • Gringo Suave
    Gringo Suave over 11 years
    This would be the best answer, but unfortunately psutil is not installable via pip.
  • heltonbiker
    heltonbiker over 10 years
    Works to get available disk on Android Phone, plugged via USB to a Windows system, running the script on Windows. Great.
  • data
    data over 10 years
    @J.F.Sebastian It depends on what you want. It is possible for Linux to reserve space for root. If you want to include this space, use f_bfree. If you want to get the number of blocks available to a user, then use f_bavail. Maybe someone can say if and how quotas are treated?
  • ovgolovin
    ovgolovin about 10 years
    I don't understand why people downvote. For example this answer may be useful to somebody. Anyway it is a good supplement for the other pupe-Pythonic solutions. If anybody doesn't like the answer is no reason to downvote it. As I understand, downvotes are for downright wrong answers. This one is not.
  • Steve Barnes
    Steve Barnes almost 10 years
    I have three niggles with the above: 1/ The docstring is wrong it returns space in Mbytes & 2/ I never like seeing more than one return statement, (too much time as a tester I guess), so would store the result in a returned value, 3/ Whole MB or decimal MB may make a difference to some people.
  • Tully
    Tully over 9 years
    psutil is now available from pypi and most other sources including debian packages.
  • Craig Ringer
    Craig Ringer about 9 years
    I can't believe how far I had to go down this question to find someone mentioning the WMI. All these crazy people using ctypes to call Windows C APIs directly when they could just use the WMI?
  • Erxin
    Erxin about 9 years
    @CraigRinger Yes, you are right. We should use the right tool to do the right thing. Most of the common management tasks for window have already been wrapped with win api in wmi. We don't have to remake the wheel. :^D
  • Erxin
    Erxin about 9 years
    @ovgolovin Up vote this answer and It is good know an other way to do the same thing.
  • Fr0zenFyr
    Fr0zenFyr over 8 years
    Why not psutil handle it?
  • DanGoodrick
    DanGoodrick about 8 years
    This is why I love stackoverflow. I did not even know about the WMI module and it worked flawlessly.
  • jayatubi
    jayatubi almost 8 years
    Why this is not the best answer?
  • jhasse
    jhasse almost 8 years
    I think because psutil wasn't always available through pypi.
  • Erxin
    Erxin over 7 years
    @Fr0zenFyr yes, that's another good option for handle this task.
  • ewerybody
    ewerybody over 5 years
    You can also check the platform via sys.platform == 'win32' sys is also available under os! So: os.sys.platform == 'win32'. Down to 2 imports! ;]
  • ewerybody
    ewerybody over 5 years
    Well, if you want to support vanilla oldschool python 2.7: You need to do these things. The less external dependencies the better. ctypes is built-in! 😐
  • ewerybody
    ewerybody over 5 years
    or os.name == 'nt'!
  • smci
    smci over 5 years
    I agree this a great answer. I fixed the stale link to psutil. Since disk_usage.free typically returns a huge 64b integer, I suggest you also want to show people disk_usage.percent. psutil.disk_usage(".").percent < 99.9 seems clearer to me...
  • pstatix
    pstatix about 3 years
    Not sure how this isn't the selected answer. Doesn't require using ctypes which can be a hassle going through MSDN docs and ensuring types are coerced correctly.
  • phoibos
    phoibos over 2 years
    IMHO this is the best way in this time and age.
  • tale852150
    tale852150 over 2 years
    Last few lines: if free_bytes.value == 0: print('dont panic') else: print(free_bytes.value)