[英]How does stat command calculate the blocks of a file?
我想知道stat
命令如何计算文件的块数。 我读过这篇文章说:
st_blocks 值给出了文件的大小,以 512 字节块为单位。 (这可能小于 st_size/512,例如当文件有漏洞时。)值 st_blksize 给出了高效文件系统 I/O 的“首选”块大小。 (以较小的块写入文件可能会导致读取-修改-重写效率低下。)
然而我无法用我自己的测试来验证这一点。
我的文件系统是ext3。
命令dumpe2fs -h /dev/sda3
显示:
...
First block: 0
Block size: 4096
Fragment size: 4096
...
然后我跑
kent@KentT60:~/Desktop$ stat Email
File: `Email'
Size: 965 Blocks: 8 IO Block: 4096 regular file
Device: 80ah/2058d Inode: 746095 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Access: 2009-08-11 21:36:36.000000000 +0200
Modify: 2009-08-11 21:36:35.000000000 +0200
Change: 2009-08-11 21:36:35.000000000 +0200
如果这里的“Blocks”意思是:“有多少个512字节的块”,那么这个数字应该是2,而不是8。我以为文件系统的块大小(IO块)是4k。
如果文件系统获取文件Email
,它将从磁盘(8 x 512 字节块)中获取至少 4k,这意味着 965/512 + 6 = 8。我不确定这个猜测是否正确。
另一个测试:
kent@KentT60:~/Desktop$ stat wxPython-demo-2.8.10.1.tar.bz2
File: `wxPython-demo-2.8.10.1.tar.bz2'
Size: 3605257 Blocks: 7056 IO Block: 4096 regular file
Device: 80ah/2058d Inode: 746210 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Access: 2009-08-12 21:45:45.000000000 +0200
Modify: 2009-08-12 21:43:46.000000000 +0200
Change: 2009-08-12 21:43:46.000000000 +0200
3605257/512=7041.xx = 7042
按照我上面的猜测,这将是 7042 + 6 = 7048。但stat
结果显示 7056。
另一个例子来自互联网https://www.computerhope.com/unix/stat.htm
。 我在页面底部粘贴了示例:
File: `index.htm'
Size: 17137 Blocks: 40 IO Block: 8192 regular file
Device: 8h/8d Inode: 23161443 Links: 1
Access: (0644/-rw-r--r--) Uid: (17433/comphope) Gid: ( 32/ www)
Access: 2007-04-03 09:20:18.000000000 -0600
Modify: 2007-04-01 23:13:05.000000000 -0600
Change: 2007-04-02 16:36:21.000000000 -0600
在此示例中,文件系统块大小为 8k。 我想“块”值应该是 16xN,但它是 40。我迷路了......
谁能解释stat
如何计算“块”值?
谢谢!
stat
命令行工具使用stat
/ fstat
等函数,它们返回stat
结构中的stat
。 stat
结构的st_blocks
成员返回:
实际分配在磁盘上的大小为 512 字节的物理块总数。 没有为块特殊文件或字符特殊文件定义该字段。
因此,对于您的“电子邮件”示例,大小为 965,块数为 8,这表明在磁盘上物理分配了 8*512=4096 字节。 它不是 2 的原因是磁盘上的文件系统不是以 512 为单位分配空间的,它显然是以 4096 为单位分配的。(并且分配单位可能因文件大小和文件系统复杂程度而异。例如 ZFS 支持不同分配单位。)
同样,对于 wxPython 示例,它表示在磁盘上物理分配了 7056*512 字节或 3612672 字节。 你明白了。
IO 块大小是“关于 I/O 操作的‘最佳’单元大小的提示”——它通常是物理磁盘上的分配单元。 不要混淆 IO 块和stat
用来指示物理大小的块; 物理大小的块总是 512 字节。
根据评论更新:
就像我说的, st_blocks
是操作系统指示磁盘上文件使用了多少空间的方式。 磁盘上的实际分配单位是文件系统的选择。 例如,ZFS 可以具有可变大小的分配块,即使在同一个文件中,因为它分配块的方式:文件开始时块大小很小,块大小不断增加,直到达到特定点。 如果文件后来被截断,它可能会保留旧的块大小。 因此,根据文件的历史记录,它可以有多种可能的块大小。 因此,给定文件大小,为什么它具有特定的物理大小并不总是很明显。
具体示例:在我的 Solaris 机器上,使用 ZFS 文件系统,我可以创建一个非常短的文件:
$ echo foo > test
$ stat test
Size: 4 Blocks: 2 IO Block: 512 regular file
(irrelevant details omitted)
OK,小文件,2个块,这个文件的物理磁盘使用量为1024。
$ dd if=/dev/zero of=test2 bs=8192 count=4
$ stat test2
Size: 32768 Blocks: 65 IO Block: 32768 regular file
好的,现在我们看到物理磁盘使用量为 32.5K,IO 块大小为 32K。 然后我将它复制到test3
并在编辑器中截断了这个test3
文件:
$ cp test2 test3
$ joe -hex test3
$ stat test3
Size: 4 Blocks: 65 IO Block: 32768 regular file
现在,这是一个包含 4 个字节的文件——就像test
一样——但它在磁盘上实际使用了 32.5K,这是因为 ZFS 文件系统分配空间的方式。 块大小随着文件变大而增加,但当文件变小时它们不会减小。 (是的,这可能会导致大量空间浪费,具体取决于您在 ZFS 上执行的文件类型和文件操作,这就是为什么它允许您在每个文件系统的基础上设置最大块大小,并动态更改它。)
希望您现在可以理解文件大小和物理磁盘使用之间不一定存在简单的关系。 即使在上面,也不清楚为什么需要 32.5K 字节来存储大小正好为 32K 的文件 - 似乎 ZFS 通常需要额外的 512 字节来为其自身提供额外的存储空间。 也许它正在使用该存储进行校验和,引用计数,交易状态 - 文件系统簿记。 通过在指示的物理文件大小中包含这些额外内容,ZFS 似乎试图不误导用户关于文件的物理成本。 这并不意味着在不了解有关底层文件系统实现的详细细节的情况下对计算进行逆向工程是微不足道的。
在这里我们需要观察一件事,数据块分配是以下面指定的方式完成的:
1)默认情况下,即使我们在文件中写入一个字节的数据,也会为一个文件分配 8 个数据块。 2)当我们完成在文件中添加8*4096字节的数据后,如果我们添加一个额外的字节,则会再次分配新的8个数据块。 所以,总共 16 个数据块。
如果您理解以上语句,那么 --------(在问题中)----------------- 所以对于 965,默认情况下将分配 8 个数据块当它正好是 4*4096=32768 并且如果我们添加另一个字节来填充所有这些时,那么将分配 8 个数据块,并且对于 32769 的大小,总共将分配 16 个数据块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.