如何理解 stat 命令显示的 Blocks 和 IO Block

本文详细解析了stat命令中Blocks和IOBlock的概念,澄清了它们在Linux文件系统中的含义,指出Blocks表示512字节的块数,而IOBlock是系统的最小寻址单元。通过实例和源码分析,纠正了关于这两个概念的常见误解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景描述

待测文件:README

实际大小 8755 字节,约等于 8.6K

$ ls -l README 
-rw-r--r-- 1 liyongjun liyongjun 8755 125  2018 README
$ ls -lh README 
-rw-r--r-- 1 liyongjun liyongjun 8.6K 125  2018 README

占用空间 12K

$ du -h README 
12K	README

stat 显示

$ stat README 
  File: README
  Size: 8755      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1726296     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/liyongjun)   Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000

疑惑

stat 命令显示的 Blocks 和 IO Block 是什么意思?因为很显然:

Size 不等于 Blocks * IO Block
占用空间 也不等于 Blocks * IO Block


明确一:IO Block

$stat LICENSE 
  File: LICENSE
  Size: 18348     	Blocks: 40         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1713584     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/liyongjun)   Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000

$ stat Makefile
  File: Makefile
  Size: 43176     	Blocks: 88         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1724286     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/liyongjun)   Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:51.000000000
Modify: 2020-06-27 03:22:49.000000000
Change: 2020-12-18 14:08:37.000000000

  发现对于任意文件,IO Block 恒为 4096,可以推断出这是个固定值,含义为:文件系统的最小寻址单元
在这里插入图片描述
  扇区为 512 字节,IO Block 为 4096,说明当前系统将 8 个扇区做为一个
  对于文件系统而言,它能读写的最小粒度为 1 个 IO Block,此处为 4K。

令人疑惑的 Blocks

  唯一的疑惑就是 Blocks 了。
  网上搜索到的答案都是:表示块数、占用空间 = Blocks * IO Block。很显然这些都是错误答案,至少不适用于我当前使用的系统(应该只有 IO Block 为 512 字节的系统,才适用于:占用空间 = Blocks * IO Block)。总之,互连网上充斥着很多未经验证的错误答案,甚至曝光量比正确答案都多,这一现象真让人痛心!
  既然没人给出正解,那只能靠自己了。万法归一,查看源码。
  阅读 stat.c,发现 Blocks 和 IO Block 分别对应于 stat 结构中的 st_blocks 和 st_blksize

// 作了部分删减
struct stat
  {
    __dev_t st_dev;		/* Device.  */
    unsigned short int __pad1;
    __ino_t __st_ino;			/* 32bit file serial number.	*/
    __mode_t st_mode;			/* File mode.  */
    __nlink_t st_nlink;			/* Link count.  */
    __uid_t st_uid;		/* User ID of the file's owner.	*/
    __gid_t st_gid;		/* Group ID of the file's group.*/
    __dev_t st_rdev;		/* Device number, if device.  */
    __off_t st_size;			/* Size of file, in bytes.  */

    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */

    __ino64_t st_ino;			/* File serial number.	*/
  };
  • st_blocks Number 512-byte blocks allocated. 分配的块数,以 512 字节为单位
  • st_blksize Optimal block size for I/O. 最优的 IO 块大小,可以理解为 best I/O block size

  所以,重点,Blocks 指的是以 512 字节为单位的块的数量,或者理解为扇区数,因为一个扇区就是 512 字节。

再回首

  再回头看 stat 展示的信息

$ stat README 
  File: README
  Size: 8755      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1726296     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/liyongjun)   Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000

  Blocks 为 24,那大小就是 512 * 24 = 12K,和 du 展示的占用空间大小一致。即 占用空间 = Blocks * 512

### Linux 中 `stat` 命令的功能及参数详解 #### 功能概述 `stat` 是一个用于显示文件或文件系统状态的命令工具。它能够提供关于文件的各种元数据信息,例如文件大小、权限、时间戳以及底层存储细节等[^1]。 --- #### 参数说明 以下是常用的 `stat` 命令参数及其作用: 1. **默认行为** 当运行 `stat 文件名` 时,默认会输出该文件的详细属性信息,包括但不限于文件名称、大小、数、I/O 大小、设备号、inode 编号、链接数量、访问权限、UID GID、访问时间(Access)、修改时间(Modify)变更时间(Change)。如果支持,则还会显示创建时间(Birth)[^2]。 示例: ```bash stat example.txt ``` 2. **自定义格式化输出 (`-c/--format`)** 使用 `-c` 或 `--format` 可以按照指定的格式输出文件的信息。这允许用户仅提取感兴趣的字段并控制其展示方式。 格式字符串中的占位符可以替换为实际值。例如: - `%n`: 文件名 - `%s`: 文件总字节数 - `%a`: 权限模式作为八进制表示 示例:只打印文件名文件大小。 ```bash stat -c "%n: %s bytes" example.txt ``` 3. **无换行格式化输出 (`--printf`)** 这一选项类似于 `-c`,但它不会自动添加换行符到每条记录之后,因此适合于连续输出多个文件的结果。 示例:按特定格式输出文件名大小。 ```bash stat --printf="Name: %n, Size: %s bytes\n" example.txt ``` 4. **显示文件系统信息 (`-f/--file-system`)** 如果希望查看某个路径所在文件系统的整体统计信息而非单个文件的数据,则可使用此标志。此类信息通常涉及文件系统的类型、挂载点位置以及其他特性描述。 示例:获取 `/home` 目录下文件系统的详情。 ```bash stat -f /home ``` --- #### 时间戳解释 通过执行标准形式下的 `stat` 调用可以获得三个主要的时间戳标记: - **Access**: 上次读取操作发生的具体时刻; - **Modify**: 数据最后一次被更改的确切日期与时间; - **Change**: 属性最后变动瞬间;即使内容未变但比如所有权转移也算作一次 change event[^2]。 注意,在某些较老版本的操作系统或者特殊类型的文件系统里可能缺乏 birth time 支持。 --- ```python import os from datetime import datetime def get_file_stats(file_path): stats = os.stat(file_path) access_time = datetime.fromtimestamp(stats.st_atime).strftime('%Y-%m-%d %H:%M:%S') modify_time = datetime.fromtimestamp(stats.st_mtime).strftime('%Y-%m-%d %H:%M:%S') change_time = datetime.fromtimestamp(stats.st_ctime).strftime('%Y-%m-%d %H:%M:%S') result = { 'File': file_path, 'Size': f'{stats.st_size} Bytes', 'Blocks': stats.st_blocks, 'IO_Block': stats.st_blksize, 'Device': hex(stats.st_dev), 'Inode': stats.st_ino, 'Links': stats.st_nlink, 'Permissions': oct(stats.st_mode)[-4:], 'User ID': stats.st_uid, 'Group ID': stats.st_gid, 'Access Time': access_time, 'Modification Time': modify_time, 'Status Change Time': change_time } return result print(get_file_stats('example.txt')) ``` 上述 Python 脚本展示了如何利用内置库模拟部分 `stat` 行为来检索本地文件的状态报告。 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li-Yongjun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值