我使用shutil.disk_usage()函数来查找特定路径的当前磁盘使用情况(可用量、已使用量等)。据我所知,这是一个围绕os.statvfs()调用的 Package 器。我发现它没有给出我所期望的答案,与Linux中的“du”的输出相比。
出于公司隐私的原因,我隐藏了下面的一些路径,但输出和代码是未经修改的。Python 3.3.2 64位版本
#!/apps/python/3.3.2_64bit/bin/python3
# test of shutils.diskusage module
import shutil
BytesPerGB = 1024 * 1024 * 1024
(total, used, free) = shutil.disk_usage("/data/foo/")
print ("Total: %.2fGB" % (float(total)/BytesPerGB))
print ("Used: %.2fGB" % (float(used)/BytesPerGB))
(total1, used1, free1) = shutil.disk_usage("/data/foo/utils/")
print ("Total: %.2fGB" % (float(total1)/BytesPerGB))
print ("Used: %.2fGB" % (float(used1)/BytesPerGB))
其输出:
/data/foo/drivecode/me % disk_usage_test.py
Total: 609.60GB
Used: 291.58GB
Total: 609.60GB
Used: 291.58GB
正如您所看到的,主要问题是我希望“Used”的第二个数量要小得多,因为它是第一个目录的子集。
/data/foo/drivecode/me % du -sh /data/foo/utils
2.0G /data/foo/utils
尽管我很信任“du”,但我发现很难相信Python模块也会不正确。因此,也许这只是我对Linux文件系统的理解可能是问题所在。:)
我写了一个模块(主要基于SO上某人的代码),它递归地获取disk_usage,我一直使用到现在。它看起来与“du”输出匹配,但比shutil.disk_usage()函数慢得多,所以我希望我能让它工作。
先谢谢你了。
4条答案
按热度按时间g52tjvyc1#
问题是shutil使用下面的
statvfs
系统调用来确定所使用的空间。据我所知,这个系统调用没有文件路径粒度,只有文件系统粒度。这意味着您提供给它的路径只能帮助识别您想要查询的文件系统,而不是路径。换句话说,您为它提供了路径
/data/foo/utils
,然后它确定哪个文件系统支持此文件路径。然后它查询 * 文件系统 *。当您考虑used
参数在shutil中是如何定义的时,这一点就变得显而易见了:其中:
这就是为什么它会提供整个文件系统上使用的 * 总 * 空间。
实际上,在我看来,
du
命令本身也会遍历文件结构并将文件大小相加。下面是GNU coreutilsdu
命令的source code。iyzzxitl2#
shutil.disk_usage
返回磁盘使用情况(即支持该路径的安装点),而不是该路径下的实际文件使用。这相当于运行df /path/to/mount
而不是du /path/to/files
。请注意,这两个目录的用法完全相同。从文档:以命名元组的形式返回有关给定路径的磁盘使用情况统计信息,该命名元组具有属性total、used和free,这些属性是总空间、已用空间和可用空间的量(以字节为单位)。
iezvtpos3#
2013年后,任何人都可以在此更新:
根据您的Python版本和操作系统,
shutil.disk_usage
可能支持path
变量的文件和目录。以下是细分:Windows:
Unix:
41ik7eoe4#
由于上面已经提到这个函数报告的是disk_usage(顾名思义),而不是特定文件夹的数据使用情况,我冒昧地整理了一个非常简单明了的几行代码来计算文件夹大小。因为它是递归的;如果一个文件夹中有数十亿个文件,可能会花费一段时间/使用一点内存。