文件块大小 - stat 和 ls 之间的区别

sta*_*ona 10 ls filesystems utilities stat

我注意到当我做一个:

ls -ls file
Run Code Online (Sandbox Code Playgroud)

它提供块数,比如 8 个块。

当我做:

stat file
Run Code Online (Sandbox Code Playgroud)

我注意到块数是 16,是 ls 给出的数字的两倍。

我的文件系统上的块大小是 4096。我了解到 ls 使用的块的任意单位是 1024。说 stat 在报告块时使用 512 字节的任意单位是否正确?

如果是这样,是否有不一致的原因?

我在 ext4 文件系统上运行 Ubuntu 11.10。

Gil*_*il' 12

许多磁盘的扇区大小为 512 字节,这意味着磁盘上的任何读取或写入一次都会传输整个 512 字节的扇区。设计一个扇区不在文件之间分割的文件系统是很自然的(这会使设计复杂化并损害性能);因此文件系统倾向于为文件使用 512 字节的块。因此,诸如ls和 之类的传统实用程序du以 512 字节块为单位指示大小。

对于人类来说,512 字节的单位意义不大。1kB 是相同的数量级,而且更有意义。一个文件系统块(文件被划分成的最小单位)实际上通常由几个扇区组成:1kB、2kB和4kB是常见的文件系统块大小;所以 512 字节单元在文件系统设计中并没有充分的理由,而且除了传统之外,没有充分的理由在磁盘驱动程序之外使用 512 字节单元。

所以你有一个没有太多意义的传统,以及一个更具可读性的约定。有点像八进制和十六进制:没有对的和错的,它们是写相同数字的不同方式。

许多工具都有选择显示单位的选项:ls --block-size=512对于 GNU lsPOSIXLY_CORRECT=1在 GNUdf和 GNU的环境中设置du以获得 512 字节单位(或-k强制传递1kB 单位)。statGNU coreutils 中的命令作为“块大小”(%B值)公开的是内部接口的依赖于操作系统的值;取决于操作系统,它可能与文件系统或磁盘代码使用的大小有关,也可能无关(通常不是 - 请参阅块大小和簇大小之间的差异)。在 Linux 上,无论任何底层驱动程序在做什么,该值都是 512。的价值%B从不重要,它的存在只是一个怪癖。


Edd*_*iao 5

在深入研究源代码和 POSIX 标准后,我会说 @antje-m 和 @Gilles 的答案大部分是正确的。

值得引用POSIX.1-2008的评论,作为总结:

512 字节单元的使用是历史惯例,并在本卷 POSIX.1-2008 中保持与 ls 和其他实用程序的兼容性。这并不强制要求文件系统本身基于 512 字节的块。-k 选项是作为折衷措施添加的。标准开发人员一致认为 512 字节是最好的默认单位,因为它在 System V 上具有完全的历史一致性(相对于 BSD 系统上的 512/1024 字节混合使用),并且 -k 选项可以切换到 1024-字节单位是一个很好的折衷方案。喜欢更符合逻辑的 1024 字节数量的用户可以轻松地将 df 别名为 df -k,而不会破坏许多依赖 512 字节单位的历史脚本。

对于 中的块大小ls -s

POSIX默认块大小是实现定义的,除非-k给出选项。

中实现的默认块大小GNU coreutils ls定义为GNU gnulibgnulib/lib/human.c

/* The default block size used for output.  This number may change in
   the future as disks get larger.  */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif
Run Code Online (Sandbox Code Playgroud)

它来自一个旧的提交:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <jim@meyering.net>
Date:   Mon Jun 29 15:23:04 1998 +0000
Run Code Online (Sandbox Code Playgroud)

提交消息本身没有说明数字 1024。

并注意所使用的块大小dudf也是1024,ls只是选择了由他们。虽然 fordudf它与 POSIX 标准有冲突(所以这里环境变量POSIXLY_CORRECT来了)。这似乎是 GNU 团队的决定,请参阅有关此争议的维基百科页面POSIX

对于命令stat.

它不是 POSIX 标准的一部分,但系统调用是。但是块大小的单位没有标准化(sys_stat.h):stat

POSIX.1-2008 中未定义 stat 结构的 st_blocks 成员的单位。

stat命令仅显示stat系统调用提供的信息,并使用 512 块大小,几乎没有例外(它们是非 Linux,例如 HP-UX、IBM AIX 等。请参阅 中定义的宏gnulib/lib/stat-size.h)。

所以数字 512 更像是一个历史选择和 Linux 惯例。

GNU coreutils(因此ls命令)不Linux内核(因此的一部分stat呼叫)时,他们的目标是不同的系统方面中,GNU coreutils则多为人类(更易于阅读),和Linux内核对硬件抽象(因此更接近于硬件)。

编辑:4096 块大小是“IO 块”大小,实际物理块大小可能仍然是 512 字节,如本问题所述