在OS/X上使用Python查找可用磁盘空间

25

我想知道我的硬盘上有多少空闲字节,但在Python中做起来有些困难。

我尝试了以下方法:

import os

stat = os.statvfs(path)
print stat.f_bsize * stat.f_bavail

但是,在OS/X上,它给了我一个17529020874752字节的数字,大约是1.6TB,这听起来很棒,但不幸的是并不完全正确。

如何最好地得出这个数字?


1
在https://dev59.com/pnVD5IYBdhLWcg3wNYxZ#2372171中讨论了一种跨平台的方法。 - Roman Starkov
7个回答

39

尝试使用f_frsize而不是f_bsize

>>> s = os.statvfs('/')
>>> (s.f_bavail * s.f_frsize) / 1024
23836592L
>>> os.system('df -k /')
Filesystem   1024-blocks     Used Available Capacity  Mounted on
/dev/disk0s2   116884912 92792320  23836592    80%    /

不确定为什么,但只有当我将块大小(1024)更改为512时,这才对我起作用。 - MFB
1
你使用的是哪个操作系统/Python版本? - Nicholas Riley
这是过时的API。https://docs.python.org/2/library/statvfs.html#module-statvfs - JohnTortugo
3
不是的。在Python 3.x中,statvfs 模块已被弃用或删除(这是一种将statvfs输出作为元组索引公开,而不是作为对象属性的旧方法),但我在答案中没有使用该模块。然而,os.statvfs 并没有被弃用——事实上,它甚至在3.6中得到更新:https://docs.python.org/3.6/library/os.html#os.statvfs。为了适应现代Python,唯一需要修改的是使用整数除法(`//`), 不过像另一个答案中所述的shutil.disk_usage肯定是更简单的选择! - Nicholas Riley
Python 3.8中出现AttributeError: module 'os' has no attribute 'statvfs'错误。 - kloddant
@kloddant 这取决于平台,这就是为什么(10.5年前)我问他们使用的操作系统是什么。os.statvfs在Python 3.11中仍然存在,并带有可用性说明。https://docs.python.org/3.11/library/os.html#os.statvfs - Nicholas Riley

19

在UNIX系统中:

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)

用法:

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

对于Windows,你可以使用psutil


谢谢您分享这个代码!我认为它比使用子进程和调用 df 命令的其他解决方案更好。 - guettli
这是弃用的API。https://docs.python.org/2/library/statvfs.html#module-statvfs - JohnTortugo
不是这样的。请参见我上面答案中的评论(https://dev59.com/PnRA5IYBdhLWcg3w6SNH#787832)。 - Nicholas Riley

16

在 Python 3.3 及以上版本,shutil 提供了相同的功能。

>>> import shutil
>>> shutil.disk_usage("/")
usage(total=488008343552, used=202575314944, free=260620050432)
>>> 

它能够工作,小巧优雅,完美(如果您有 Python 3.3+)。 - Andrzej Rehmann

4

Psutil 模块 也可以使用。

>>> psutil.disk_usage('/')
usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)

文档可以在这里找到。


0
def FreeSpace(drive):
    """ Return the FreeSape of a shared drive in bytes"""
    try:
        fso = com.Dispatch("Scripting.FileSystemObject")
        drv = fso.GetDrive(drive)
        return drv.FreeSpace
    except:
        return 0

-1

它不是独立于操作系统的,但在Linux上可以工作,并且很可能在OS X上也可以:

print commands.getoutput('df .').split('\n')[1].split()[3]

它是如何工作的?它获取'df .'命令的输出,该命令提供有关当前目录所在分区的磁盘信息,将其分成两行(就像打印到屏幕上一样),然后获取其中的第二行(通过在第一个拆分()之后附加[1]),然后将行拆分为不同的以空格分隔的部分,最后给出该列表中的第4个元素。

>>> commands.getoutput('df .')
'Filesystem           1K-blocks      Used Available Use% Mounted on\n/dev/sda3             80416836  61324872  15039168  81% /'

>>> commands.getoutput('df .').split('\n')
['Filesystem           1K-blocks      Used Available Use% Mounted on', '/dev/sda3             80416836  61324908  15039132  81% /']

>>> commands.getoutput('df .').split('\n')[1]
'/dev/sda3             80416836  61324908  15039132  81% /'

>>> commands.getoutput('df .').split('\n')[1].split()
['/dev/sda3', '80416836', '61324912', '15039128', '81%', '/']

>>> commands.getoutput('df .').split('\n')[1].split()[3]
'15039128'

>>> print commands.getoutput('df .').split('\n')[1].split()[3]
15039128

иҝҷз§Қ方法并дёҚжҳҜйқһеёёеҸҜйқ пјҢеӣ дёәиҺ·еҸ–dfзҡ„з»“жһ„еҢ–иҫ“еҮәжІЎжңүеҸҜ移жӨҚзҡ„ж–№жі•гҖӮдҫӢеҰӮпјҢе°қиҜ•жҢӮиҪҪLVMжҲ–NFSеҚ·пјҢе®ғе°ҶејҖе§Ӣе°Ҷиҫ“еҮәеҲҶејҖи·Ёи¶ҠеҮ иЎҢгҖӮ - conny

-5

出了什么问题?

import subprocess
proc= subprocess.Popen( "df", stdout=subprocess.PIPE )
proc.stdout.read()
proc.wait()

4
使用纯Python意味着它与操作系统无关。 :) - PKKid
3
它很脆弱,因为它依赖于外部应用程序来保持恒定的格式,而不是系统库。 - Shane C. Mason
这并不意味着被接受的答案在操作系统上无差别...我的Windows上的2.6安装没有os.statvfs - Roman Starkov
2
@Shane C. Mason:“依赖于外部应用程序”。该外部应用程序由POSIX标准严格定义。它与库一样是操作系统的一部分,并且将永远存在。 - S.Lott
如果路径没有设置怎么办?那么用户需要知道程序的完整路径。这是一个无法接受的问题。 - ironMover

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接