您好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
如您所见,主要问题是我希望“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()”函数要慢得多,因此我希望可以使它工作。
在此先感谢。
最佳答案
问题在于,shutil使用下面的 statvfs
系统调用来确定所使用的空间。据我所知,此系统调用没有文件路径粒度,只有文件系统粒度。这意味着您提供给它的路径仅有助于识别要查询的文件系统,而不是路径。
换句话说,您给它提供了路径/data/foo/utils
,然后确定了哪个文件系统支持该文件路径。然后,它查询文件系统。当您考虑在shutdownil中如何定义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。关于python - 在shutil.disk_usage()中似乎有差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19236690/