使用Python计算跨平台卷上的剩余空间

76

我需要一种使用Python在Linux、Windows和OS X上确定磁盘卷剩余空间的方法。目前,我正在解析各个系统调用(如df、dir)的输出来完成此操作 - 是否有更好的方法?


1
请查看这里的代码示例: http://code.activestate.com/recipes/577972-disk-usage/?in=user-4178764 - Giampaolo Rodolà
12个回答

79
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
请注意,您必须传递目录名称才能使 GetDiskFreeSpaceEx() 函数工作(statvfs() 函数可用于文件和目录)。您可以使用 os.path.dirname() 从文件中获取目录名称。
此外,请参阅os.statvfs()GetDiskFreeSpaceEx 的文档。

13
.f_bfree是文件系统中空闲块的总数。需要乘以.f_bsize以获取字节数。 - jfs
9
至少在OS X Lion / Python 2.7上,我注意到通过乘以.f_bsize得到的值要大得多,因为f_bsize首选块大小,而.f_frsize基本块大小并给出正确的值。在我的Linux测试系统上,两个值都是相同的,因此.f_frsize应该始终可用。 - Dennis Bliefernicht
1
可以通过在 Windows 系统上运行脚本,获取通过 USB 连接到 Windows 系统的 Android 手机上可用的磁盘空间。太棒了! - heltonbiker
@J.F.Sebastian 这取决于你想要什么。Linux 可以为 root 保留空间。如果你想包括这个空间,使用 f_bfree。如果你想获取用户可用的块数,则使用 f_bavail。也许有人可以说一下配额是如何处理的? - data
或者 os.name == 'nt' - ewerybody
显示剩余2条评论

34

使用pip install psutil安装psutil。然后,您可以使用以下代码获取可用空间的字节数:

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

2
为什么这不是最佳答案? - jayatubi
2
我认为这是因为psutil并不总是通过pypi可用。 - jhasse
我同意这是一个很好的答案。我修复了指向 psutil 的陈旧链接。由于 disk_usage.free 通常返回一个巨大的64位整数,我建议您还要向人们展示 disk_usage.percent。对我来说,psutil.disk_usage(".").percent < 99.9 更清晰... - smci

30
你可以使用wmi模块适用于Windows,os.statvfs适用于Unix。
对于Windows。
import wmi

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

适用于Unix或Linux操作系统

from os import statvfs

statvfs(path)

2
我简直不敢相信我要在这个问题里继续查找到有人提到WMI。所有这些疯狂的人直接使用ctypes调用Windows C API时,他们为什么不只是使用WMI呢? - Craig Ringer
1
@CraigRinger 是的,你说得对。我们应该使用正确的工具来做正确的事情。大多数窗口的常见管理任务已经在WMI中用Win API封装好了。我们不必重复造轮子。 :^D - Erxin
为什么不让psutil处理它? - Fr0zenFyr
2
这就是为什么我喜欢stackoverflow。我甚至不知道WMI模块,但它却完美地工作了。 - DanGoodrick
@Fr0zenFyr 是的,这是另一个处理此任务的好选择。 - Erxin
1
如果你想支持纯净的老式Python 2.7:你需要做这些事情。外部依赖越少,越好。 ctypes是内置的! - ewerybody

18

如果您正在运行Python3:

使用shutil.disk_usage()os.path.realpath('/')名称规范化一起工作:

from os import path
from shutil import disk_usage

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

或者

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)

提供给您以MB为单位的总空间、已用空间和可用空间。


不确定为什么这不是被选中的答案。它不需要使用 ctypes,这可能需要查阅 MSDN 文档并确保类型被正确强制转换,这很麻烦。 - pstatix
在我看来,这是当前最好的方式。 - phoibos

10

如果您不想添加其他依赖项,您可以在Windows上使用ctypes直接调用win32函数调用。

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'

最后几行代码:如果 free_bytes.value 等于 0: 打印 '别慌' 否则: 打印 free_bytes.value - tale852150

6

这可能是最好的答案,但不幸的是psutil无法通过pip安装。 - Gringo Suave
1
psutil现在可以从pypi和大多数其他来源(包括Debian软件包)获取。 - Tully

6

从Python 3.3开始,您可以使用标准库中的shutil.disk_usage("/").free命令在Windows和UNIX系统上获取磁盘空间信息。


4
你可以使用df作为跨平台的方式。它是GNU核心工具的一部分。这些核心工具应该存在于每个操作系统中。然而,在Windows上它们不是默认安装的(在这里,GetGnuWin32非常有用)。 df是一个命令行实用程序,因此需要包装器用于脚本编写。 例如:
from subprocess import PIPE, Popen

def free_volume(filename):
    """Find amount of disk space available to the current user (in bytes) 
       on the file system containing filename."""
    stats = Popen(["df", "-Pk", filename], stdout=PIPE).communicate()[0]
    return int(stats.splitlines()[1].split()[3]) * 1024

4
我不理解为什么人们会踩。例如,这个答案可能对某些人有用。无论如何,它是其他 Pupy-Pythonic 解决方案的很好的补充。如果有人不喜欢这个答案,也没有理由踩它。据我所知,踩是用来针对完全错误的答案的。而这个答案并非如此。 - ovgolovin
@ovgolovin 给这个答案点个赞,知道另一种实现方式也是很好的。 - Erxin

1
以下代码在Windows上返回正确的值。
import win32file    

def get_free_space(dirname):
    secsPerClus, bytesPerSec, nFreeClus, totClus = win32file.GetDiskFreeSpace(dirname)
    return secsPerClus * bytesPerSec * nFreeClus

1

os.statvfs() 函数是获取 Unix-like 平台(包括 OS X)上该信息的更好方法。Python 文档说“可用性:Unix”,但值得检查它是否也适用于你所构建的 Python 的 Windows 版本(即,文档可能已经不是最新的)。

否则,您可以使用 pywin32 库直接调用 GetDiskFreeSpaceEx 函数。


3
os.statvfs() 不适用于 Windows 系统(Python 2.5.2 -- 当前生产版本)。 - jfs

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