【问题标题】:Get actual disk space of a file获取文件的实际磁盘空间
【发布时间】:2011-05-15 13:33:13
【问题描述】:

如何在 python 中获取磁盘上的实际文件大小? (它在硬盘上的实际大小)。

【问题讨论】:

  • 您的意思是按集群大小进行汇总?
  • @ruslik:没那么简单。考虑例如稀疏或压缩文件,它们占用的空间比其大小所指示的要少。

标签: python


【解决方案1】:

仅限 UNIX:

import os
from collections import namedtuple

_ntuple_diskusage = namedtuple('usage', 'total used free')

def disk_usage(path):
    """Return disk usage statistics about the given path.

    Returned valus is a named tuple with attributes 'total', 'used' and
    'free', which are the amount of total, used and free space, in bytes.
    """
    st = os.statvfs(path)
    free = st.f_bavail * st.f_frsize
    total = st.f_blocks * st.f_frsize
    used = (st.f_blocks - st.f_bfree) * st.f_frsize
    return _ntuple_diskusage(total, used, free)

用法:

>>> disk_usage('/')
usage(total=21378641920, used=7650934784, free=12641718272)
>>>

编辑 1 - 也适用于 Windows:https://code.activestate.com/recipes/577972-disk-usage/?in=user-4178764

编辑 2 - 这在 Python 3.3+ 中也可用:https://docs.python.org/3/library/shutil.html#shutil.disk_usage

【讨论】:

    【解决方案2】:

    这是在设置了st_blocks 的平台上获取磁盘上文件大小的正确方法:

    import os
    
    def size_on_disk(path):
        st = os.stat(path)
        return st.st_blocks * 512
    

    表明乘以os.stat(path).st_blksizeos.vfsstat(path).f_bsize 的其他答案完全不正确。

    Python documentation for os.stat_result.st_blocks 非常明确地指出:

    st_blocks
    为文件分配的 512 字节块数。当文件有漏洞时,这可能小于st_size/512。

    此外,stat(2) man page 也说了同样的话:

    blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
    

    【讨论】:

      【解决方案3】:

      2021-03-26 更新:以前,我的回答将文件的逻辑大小四舍五入为块大小的整数倍。这种方法仅适用于文件存储在磁盘上的连续块序列中(或者如果所有块都已满,只有一个块除外)。由于这是一种特殊情况(尽管对于小文件很常见),因此我更新了我的答案以使其更普遍正确。但是,请注意,很遗憾,statvfs 方法和 st_blocks 值在某些系统(例如 Windows 10)上可能不可用。

      调用 os.stat(filename).st_blocks 获取文件中的块数。

      调用 os.statvfs(filename).f_bsize 获取文件系统块大小。

      然后计算正确的磁盘大小,如下:

      num_blocks = os.stat(filename).st_blocks
      block_size = os.statvfs(filename).f_bsize
      sizeOnDisk = num_blocks*block_size
      

      【讨论】:

      • ((lSize-1)/bSize+1)*bSize) 可能更准确一些。感谢您纠正我古老而错误的答案。
      • Deprecated since version 2.6: The statvfs module has been removed in Python 3. :-( docs.python.org/2/library/statvfs.html
      • @danodonovan 看起来statvfs 模块已在 Python 3 中删除,但答案使用了os 模块。如您所见,documentation for Python 3 表明os.statvfs 仍然存在,甚至在 Python 3.6 中还包含新功能。
      • 我遇到的情况是文件较大,您的两个公式都给我的值比 du 给我的值小 1 个块(4,096 字节)。例如,如果您使用命令dd if=/dev/zero of=testsize bs=1 count=419472426 创建文件。换句话说,du 使用 --apparent-size 选项的结果之间的差异是 7,126 而不是 4,096。注意:du 的 --apparent-size 选项的值与使用 os.stat(filename).st_size 获得的值匹配。
      【解决方案4】:
      st = os.stat(…)
      du = st.st_blocks * st.st_blksize
      

      【讨论】:

      • +1,没有意识到这是在os.stat!我正准备将提问者转介给win32file.DeviceIoControl。不知道为什么我认为 OP 在 Windows 上:P
      • "在某些 Unix 系统(如 Linux)上,以下属性也可能可用:st_blocks(为文件分配的块数)、st_blksize(文件系统块大小)..." – 即不是可移植的,并且您至少应该捕获这些成员不可用时引发的异常。
      • 小心,这是错误的!在 Linux 上,st.st_blocks总是以 512 字节为单位,而st.st_blksize 是文件系统块大小(通常为 4096 字节)。真正的用法是st.st_blocks * 512。详情请见linux.die.net/man/2/stat
      • 不,你们都错了:st.st_blocks 并不总是以 512 字节为单位。在我的机器上,它以 1024 为单位(这确实很奇怪)。此外,答案是错误的,因为 st_blksize 不返回 1024,它返回 FILE I/O 块大小,例如,st_blksize 在我的机器上返回 65536。例如,在我的戴尔笔记本电脑上,在 Windows 7 的 cygwin 上运行 python 2.7.8,我创建了一个 3000Byte 的文件(“dd if=/dev/zero bs=3000 count=1 of=./testfile.txt”)和:os .stat("testfile.txt").st_blocks=4; os.stat("./testfile.txt").st_blksize=65536;逻辑大小是3000,磁盘上是4096。我会在下面回答
      • 您能否更新您的答案以参考下面@hft 的答案?
      【解决方案5】:

      我不确定这是磁盘大小还是逻辑大小:

      import os
      filename = "/home/tzhx/stuff.wev"
      size = os.path.getsize(filename)
      

      如果不是您要寻找的机器人,您可以将其除以簇大小(如浮点数),然后使用 ceil,然后相乘。

      【讨论】:

      • 当我在 windows7,python 2.2 中使用 getsize() 时,我确实得到了文件实际占用的空间。就我而言,我渴望只是“文件大小”而不是“文件空间”。我想知道你怎么能得到文件大小
      【解决方案6】:

      要获取给定文件/文件夹的磁盘使用情况,您可以执行以下操作:

      import os
      
      def disk_usage(path):
          """Return cumulative number of bytes for a given path."""
          # get total usage of current path
          total = os.path.getsize(path)
          # if path is dir, collect children
          if os.path.isdir(path):
              for file_name in os.listdir(path):
                  child = os.path.join(path, file_name)
                  # recursively get byte use for children
                  total += disk_usage(child)
          return total
      

      该函数递归地收集嵌套在给定路径中的文件的字节使用量,并返回整个路径的累积使用量。 如果您想打印每个文件的信息,也可以在其中添加print "{path}: {bytes}".format(path, total)

      【讨论】:

      • 在运行多个测试后,在 Windows 7 上这将返回实际大小,而不是磁盘上的大小。
      猜你喜欢
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 2015-11-06
      • 2019-12-12
      • 2010-11-26
      • 2012-11-15
      • 2012-12-24
      相关资源
      最近更新 更多