Hello StackOverflow人员, 长期读者,第一次海报。希望我在这里得到所有信息以提出一个有用的问题。
我正在使用shutil.disk_usage()函数来查找特定路径的当前磁盘使用情况(可用,使用的数量等)。据我所知,这是os.statvfs()调用的包装器。我发现它没有给出我期望的答案,与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
正如您所看到的,主要问题是我希望“使用”的第二个数量要小得多,因为它是第一个目录的子集。
/data/foo/drivecode/me % du -sh /data/foo/utils
2.0G /data/foo/utils
尽管我信任“du”,但我发现很难相信Python模块也不正确。所以也许只是我对Linux文件系统的理解可能是个问题。 :)
我写了一个模块(很大程度上是基于SO的某人的代码),它递归地获取了disk_usage,直到现在我才使用它。它看起来与“du”输出相匹配,但是比shutil.disk_usage()函数慢得多,所以我希望我可以让它工作。
非常感谢。
答案 0 :(得分:5)
问题是shutil使用下面的statvfs
系统调用来确定使用的空间。据我所知,此系统调用没有文件路径粒度,只有文件系统粒度。这意味着您提供的路径仅有助于识别您要查询的文件系统,而不是路径。
换句话说,您为其指定了路径/data/foo/utils
,然后确定了哪个文件系统支持此文件路径。然后它查询文件系统。当您考虑如何在shutil:
used
参数时,这一点就变得很明显了
used = (st.f_blocks - st.f_bfree) * st.f_frsize
其中:
fsblkcnt_t f_blocks; /* size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* # free blocks */
unsigned long f_frsize; /* fragment size */
这就是为什么它会为您提供整个文件系统中使用的总空间。
实际上,在我看来,du
命令本身也会遍历文件结构并累加文件大小。这是GNU coreutils du
命令的source code。
答案 1 :(得分:4)
shutil.disk_usage
返回磁盘使用情况(即支持路径的挂载点),而不是该路径下的实际文件使用情况。它相当于运行df /path/to/mount
而不是du /path/to/files
。请注意,对于这两个目录,您的用法完全相同。
答案 2 :(得分:0)
为在2013年之后绊脚石的任何人更新:
根据您的Python版本和操作系统,shutil.disk_usage
可能支持path
变量的文件和目录。这是细分:
Windows:
Unix: