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

我想知道如何stat命令计算文件的块。 我读过这篇文章 ,它说:

值st_blocks以512字节块的forms给出文件的大小。 (这可能比st_size / 512小,例如,当文件有空洞时。)值st_blksize为高效的文件系统I / O提供“首选”块大小。 (以较小的块写入文件可能导致低效的读取 – 修改 – 重写。)

但我无法在我的testing中validation它。

我的文件系统是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 

如果这里的块的意思是:多less个512字节的块,数字应该是2而不是8个。我认为,来自文件系统(io块)的块大小是4k。 如果fs会得到电子邮件文件,它将从磁盘取得最小的4k(8 x 512字节块),这意味着965/512 + 6 = 8。我不确定猜测是否正确。

另一个testing:

 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块大小是8k。 我想块数应该是16xN,但是是40。

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

谢谢!

stat命令行工具使用stat / fstat等函数,它们以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一样 – 但是由于ZFS文件系统分配空间的方式,它在磁盘上物理地使用32.5K。 文件越大,块大小越大,但文件越小,块大小越小。 (是的,这可能会导致大量浪费的空间,这取决于您在ZFS上执行的文件和文件操作的种类,这就是为什么它允许您在每个文件系统基础上设置最大块大小并动态更改它的原因。

希望你现在应该明白,文件大小和物理磁盘使用率之间不一定是简单的关系。 即使在上面,也不清楚为什么需要32.5K字节来存储大小为32K的文件 – 看起来ZFS通常需要额外的512字节来存储自己的额外存储空间。 也许它使用的存储用于校验,引用计数,事务状态 – 文件系统簿记。 通过在指定的物理文件大小中包含这些附加内容,似乎ZFS不会误导用户文件的物理成本。 这并不意味着在不知道底层文件系统实现的详细信息的情况下对计算进行逆向工程就显得微不足道了。