stat命令如何计算文件的块?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stat命令如何计算文件的块?相关的知识,希望对你有一定的参考价值。

我想知道stat命令如何计算文件的块。我读了article,它说:

值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

如果这里的块意味着:有多少512字节块,那么数字应该是2而不是8.我认为,来自文件系统(io块)的块大小是4k。如果fs将获得文件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.但统计结果显示7056。

还有来自http://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

在此示例中,FS blocksize为8k。我认为块数应该是16xN,但它是40.迷路了......

任何人都可以解释,stat如何计算块?

谢谢!

答案

stat命令行工具使用stat / fstat等函数,它们返回stat结构中的数据。 st_blocks结构的stat成员返回:

实际在磁盘上分配的大小为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)

好的,这个文件的小文件,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个数据块。

以上是关于stat命令如何计算文件的块?的主要内容,如果未能解决你的问题,请参考以下文章

20175316 stat命令的实现-mysate

怎么查看自己计算机的端口

stat命令的实现-mysate(必做)

如何将文本文件分解成更小的块(在 Unix 上使用 C++)?

stat命令的实现-mystat

c_cpp 快速代码片段,用于在统计(阻止)/ dev / rdsk中的设备时验证fstat64和stat64的行为。