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

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

我注意到,当我执行以下操作时:

ls -ls file

它提供块计数,例如 8 个块。

当我做:

stat file

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

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

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

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

答案1

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

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

所以你有一个没有太多优势的传统,并且正在出现一个更具可读性的约定。有点像八进制和十六进制:没有正确和错误之分,它们是相同数字的不同书写方式。

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

答案2

在深入研究源代码和 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

来自旧的提交:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <[email protected]>
Date:   Mon Jun 29 15:23:04 1998 +0000

提交消息本身没有提及任何有关数字 1024 的内容。

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

为令stat

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

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字节正如这个问题所解释的

答案3

这些stat命令使用硬盘的物理块大小。自 1956 年问世以来,基本上所有硬盘都使用 512 字节块。然而,随着高级格式的推出,这种情况最近开始发生变化。

我怀疑ls' 1024byte-blocksize 也有历史原因。也许文件系统的块大小曾经很常见,为 1024,或者它用于为您提供以千字节为单位的大小。但是(至少对于GNU coreutils)您可以使用选项指定块大小--block-size=

相关内容