【问题标题】:actual size of a file文件的实际大小
【发布时间】:2025-12-22 19:00:17
【问题描述】:

我正在尝试获取仍在由另一个进程下载的文件的大小。我使用了下面的代码(我在here 找到的):

os.stat(filepath).st_blocks*512

但是,它也返回分配的文件大小。在最近的检查中,我发现这个解决方案的准确性取决于它正在运行的操作系统。目前,我的操作系统是带有 ext3 文件系统的 ubuntu 12.04 服务器。有没有另一种方法可以在 python 中找到真实的文件大小?

【问题讨论】:

  • 您看到错误大小的原因可能是下载应用程序一次为整个文件分配了空间。除非您可以接口下载过程,否则我不确定您会怎么做?
  • 可能,但问题是这个方法在另一个发行版中正常工作。
  • 使用相同的下载应用程序,相同的版本等等?
  • 是的。我刚刚备份了我的应用程序并安装了一个新的操作系统。

标签: python file metadata


【解决方案1】:

来自documentation for stat()

在某些 Unix 系统(如 Linux)上,以下属性也可能可用:

  • st_blocks - 为文件分配的 512 字节块数
  • st_blksize - 文件系统块大小
  • st_rdev - 如果是 inode 设备,则为设备类型
  • st_flags - 用户定义的文件标志

您似乎想要的是st_blocks * st_blksize。请注意,这不是文件的实际大小,即st_size 成员。块数乘以块大小将大于实际文件大小。


注意:当它说“st_blocks - 为文件分配的 512 字节块的数量”时,数字 512 实际上是依赖于系统。 The POSIX specification

stat 结构的 st_blocks 成员的单位未在 POSIX.1-2008 中定义。在某些实现中,它是 512 字节。它可能因文件系统而异。

如果st_block 属性可用,那么如果它是其他值,请不要感到惊讶。

【讨论】:

  • 看来file_stat.st_blocks * 512 给出了正确的结果,不管st_blksize。 stat 手册页 (linux.die.net/man/2/stat) 还将 st_blksize 简单描述为“用于高效文件系统 I/O 的“首选”块大小”。
  • 答案的编辑是正确的,但答案以“你似乎想要的是st_blocks * st_blksize”开头。这绝不是正确的,st_blocksst_blksize 之间没有关系。如果您可以假设 Linux,那么您可以确定它是 512 块,但我知道的唯一可移植解决方案是来自 Gnulib 的stat-size.h 的 ST_NBLOCKSIZE
【解决方案2】:

试试

os.stat(filepath).st_size

似乎它会返回您在“ls -l”中看到的内容

【讨论】:

  • 我从 ls -l 得到的也不是我想要的。
【解决方案3】:

独立于您的 SO,您可以访问文件的元数据:

metadata = os.stat(path_to_file)
metadata.st_size

【讨论】:

  • @Hgeg 然后似乎不是您想要的文件的实际大小
  • 我的意思是我想知道它在硬盘驱动器上分配了多少空间,而不是存储在 inode 中的文件大小,这是我目前得到的值。