Cross-platform space remaining on volume using python
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'
Related videos on Youtube
Admin
Updated on July 05, 2022Comments
-
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?
-
Giampaolo Rodolà almost 12 yearsSee this recipe here: code.activestate.com/recipes/577972-disk-usage/?in=user-4178764
-
-
jfs over 15 yearsos.statvfs() doesn't work on Windows (Python 2.5.2 -- current production version).
-
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 over 12 yearsAt least on OS X Lion / Python 2.7 I noticed that multiplying by
.f_bsize
gives a much too large value asf_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 over 11 yearsThis would be the best answer, but unfortunately psutil is not installable via pip.
-
heltonbiker over 10 yearsWorks to get available disk on Android Phone, plugged via USB to a Windows system, running the script on Windows. Great.
-
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 about 10 yearsI 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 almost 10 yearsI 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 over 9 yearspsutil is now available from pypi and most other sources including debian packages.
-
Craig Ringer about 9 yearsI 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 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 about 9 years@ovgolovin Up vote this answer and It is good know an other way to do the same thing.
-
Fr0zenFyr over 8 yearsWhy not
psutil
handle it? -
DanGoodrick about 8 yearsThis is why I love stackoverflow. I did not even know about the WMI module and it worked flawlessly.
-
jayatubi almost 8 yearsWhy this is not the best answer?
-
jhasse almost 8 yearsI think because psutil wasn't always available through pypi.
-
Erxin over 7 years@Fr0zenFyr yes, that's another good option for handle this task.
-
ewerybody over 5 yearsYou can also check the platform via
sys.platform == 'win32'
sys is also available underos
! So:os.sys.platform == 'win32'
. Down to 2 imports! ;] -
ewerybody over 5 yearsWell, 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 over 5 yearsor
os.name == 'nt'
! -
smci over 5 yearsI agree this a great answer. I fixed the stale link to
psutil
. Sincedisk_usage.free
typically returns a huge 64b integer, I suggest you also want to show peopledisk_usage.percent
.psutil.disk_usage(".").percent < 99.9
seems clearer to me... -
pstatix about 3 yearsNot 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 over 2 yearsIMHO this is the best way in this time and age.
-
tale852150 over 2 yearsLast few lines: if free_bytes.value == 0: print('dont panic') else: print(free_bytes.value)