【问题标题】:Seeming discrepancy in shutil.disk_usage()shutil.disk_usage() 中似乎存在差异
【发布时间】:2013-10-07 23:43:26
【问题描述】:

我正在使用 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() 函数慢得多,所以我希望我能做到这一点。

非常感谢。

【问题讨论】:

  • 函数shutil.disk_usage 是给你的“磁盘”使用而不是“目录”使用。你从中得到的应该与df -h而不是du -sh进行比较。

标签: python linux shutil


【解决方案1】:

问题是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。

【讨论】:

    【解决方案2】:

    shutil.disk_usage 返回磁盘使用情况(即支持路径的挂载点),而不是该路径下的实际文件使用情况。它相当于运行df /path/to/mount 而不是du /path/to/files。请注意,这两个目录的用法完全相同。

    来自文档:"Return disk usage statistics about the given path as a named tuple with the attributes total, used and free, which are the amount of total, used and free space, in bytes."

    【讨论】:

    • 谢谢。我想问题是,是否有一个 Python 函数更类似于路径下的文件使用?如果没有内置任何东西,我可以使用 os.walk()。这一切都解释了为什么“du”和 Python 等价物如此之快,也许目录结构已经包含这些信息(我在这里推测)并且它只是将其解析出来。而要获取文件使用情况,我需要爬取整个路径和子目录并添加文件大小。
    • 确实,除了为每个文件手动计算它之外,没有办法计算文件使用的空间量。看看这些链接,它们可能会对您有所帮助:stackoverflow.com/questions/12480367/… 另外,请注意,您必须四舍五入到块大小才能获得与 du 给您相同的数字:stackoverflow.com/questions/4080254/…
    【解决方案3】:

    针对 2013 年之后遇到此问题的任何人的更新:


    根据您的 Python 版本和操作系统,shutil.disk_usage 可能支持path 变量的文件和目录。这是细分:

    Windows:

    • 3.3 - 3.5:仅支持挂载点/文件系统
    • 3.6 - 3.7:目录支持
    • 3.8+:文件和目录支持

    Unix:

    • 3.3 - 3.5:仅支持挂载点/文件系统
    • 3.6+:文件和目录支持

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 2019-07-25
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多