如何在Windows系统中获取总磁盘大小?

3

我可以使用ctypesMEMORYSTATUSEX()获取RAM大小,但是我无法找到任何关于总磁盘大小的信息(不是可用空间,而是总容量)。


我认为你可以在这里找到答案:https://dev59.com/knVC5IYBdhLWcg3wfxM8#276934 - Lex Hobbit
@LexHobbit 这是关于RAM(内存)的,不是磁盘。 - AlwaysQuestioning
哦,抱歉您已经写过这个了 =) - Lex Hobbit
3
您可以在Python 3.3+中使用shutil.disk.usage来调用。如果需要在Python 2中使用,可以使用ctypes。 - Eryk Sun
@ErykSun 这应该是一个答案 - 目前为止最好的答案。(但你打错字了 - 应该是 shutil.disk_usage。) - Jann Poppinga
4个回答

6
ActiveState有一个相关的配方,使用Windows的GetDiskFreeSpaceEx函数。在我进行了有限的测试时,它似乎是有效的,但它有许多潜在问题,所以这里有一个大大改进且更加牢靠的版本,至少可以在Python 2.7+到3.x中工作,并且仅使用内置模块。

@Eryk Sun应该得到大部分增强的功劳/责任,因为他显然是关于使用ctypes方面的专家。

import os
import collections
import ctypes
import sys

import locale
locale.setlocale(locale.LC_ALL, '')  # set locale to default to get thousands separators

PULARGE_INTEGER = ctypes.POINTER(ctypes.c_ulonglong)  # Pointer to large unsigned integer
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.GetDiskFreeSpaceExW.argtypes = (ctypes.c_wchar_p,) + (PULARGE_INTEGER,) * 3

class UsageTuple(collections.namedtuple('UsageTuple', 'total, used, free')):
    def __str__(self):
        # Add thousands separator to numbers displayed
        return self.__class__.__name__ + '(total={:n}, used={:n}, free={:n})'.format(*self)

def disk_usage(path):
    if sys.version_info < (3,):  # Python 2?
        saved_conversion_mode = ctypes.set_conversion_mode('mbcs', 'strict')
    else:
        try:
            path = os.fsdecode(path)  # allows str or bytes (or os.PathLike in Python 3.6+)
        except AttributeError:  # fsdecode() not added until Python 3.2
            pass

    # Define variables to receive results when passed as "by reference" arguments
    _, total, free = ctypes.c_ulonglong(), ctypes.c_ulonglong(), ctypes.c_ulonglong()

    success = kernel32.GetDiskFreeSpaceExW(
                            path, ctypes.byref(_), ctypes.byref(total), ctypes.byref(free))
    if not success:
        error_code = ctypes.get_last_error()

    if sys.version_info < (3,):  # Python 2?
        ctypes.set_conversion_mode(*saved_conversion_mode)  # restore conversion mode

    if not success:
        windows_error_message = ctypes.FormatError(error_code)
        raise ctypes.WinError(error_code, '{} {!r}'.format(windows_error_message, path))

    used = total.value - free.value
    return UsageTuple(total.value, used, free.value)

if __name__ == '__main__':
    print(disk_usage('C:/'))

输出示例:

UsageTuple(total=102,025,392,128, used=66,308,366,336, free=35,717,025,792)

1
然后你应该使用这段代码。
import win32com.client as com


def TotalSize(drive):
    """ Return the TotalSize of a shared drive [GB]"""
    try:
        fso = com.Dispatch("Scripting.FileSystemObject")
        drv = fso.GetDrive(drive)
        return drv.TotalSize/2**30
    except:
        return 0

def FreeSpace(drive):
    """ Return the FreeSape of a shared drive [GB]"""
    try:
        fso = com.Dispatch("Scripting.FileSystemObject")
        drv = fso.GetDrive(drive)
        return drv.FreeSpace/2**30
    except:
        return 0

drive = r'C:'
print 'TotalSize of %s = %d GB' % (drive, TotalSize(drive))
print 'FreeSapce on %s = %d GB' % (drive, FreeSapce(drive))

enter image description here


在Python3上返回0。 - AlwaysQuestioning
1
我认为你至少应该提到它需要安装第三方的 pywin32 模块。 - martineau

1
从Python 3.3开始,您可以使用 shutil.disk_usage() 函数:
import shutil
print(shutil.disk_usage("E:\\"))

示例输出(其中E:是8GB SD卡):

usage(total=7985954816, used=852361216, free=7133593600)

这样做的好处是可以在Windows和Unix上工作,而且不需要安装第三方库!

0

如果你想查找C:驱动器或任何其他驱动器的总大小,可以使用psutil,并在disk_usage()函数中提供路径并转换为GB。在这里,我已经找到了C:驱动器的总磁盘大小。

import psutil
totalsize = psutil.disk_usage('C:').total / 2**30
print('totalsize: ',totalsize, ' GB')

1
我认为你至少应该提到 psutil 不是 Python 标准库的一部分,需要先下载并安装。 - martineau

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