代码之家  ›  专栏  ›  技术社区  ›  Kent

stat命令如何计算文件块?

  •  9
  • Kent  · 技术社区  · 15 年前

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

    值st_blocks给出文件大小(512字节块)。(这可能比ST U SIZE/512小,例如,当文件有孔时。)ST U 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收到文件电子邮件,它将从磁盘(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块大小是8k。我想块的编号应该是16xn,但它是40。迷路…

    任何人都能解释,统计数据是如何计算数据块的?

    谢谢!

    2 回复  |  直到 6 年前
        1
  •  17
  •   Barry Kelly    15 年前

    这个 stat 命令行工具使用 斯达 / fstat 等函数,返回 斯达 结构。这个 st_blocks 会员 斯达 结构返回:

    磁盘上实际分配的512字节大小的物理块总数。此字段不是为块特殊文件或字符特殊文件定义的。

    因此,对于您的“email”示例,大小为965,块计数为8,这表明磁盘上实际分配了8*512=4096字节。之所以不是2,是因为磁盘上的文件系统没有以512为单位分配空间,显然是以4096为单位分配空间。(分配单元可能因文件大小和文件系统的复杂性而有所不同。例如,ZFS支持不同的分配单位。)

    同样,对于wxpython示例,它指示在磁盘上物理分配7056*512字节或3612672字节。你明白了。

    IO块大小是“关于I/O操作的‘最佳’单元大小的提示”——它通常是物理磁盘上的分配单元。不要混淆IO块和 斯达 用于指示物理大小;物理大小的块始终为512字节。

    基于注释更新:

    就像我说的, ST块 操作系统如何指示磁盘上的文件使用了多少空间。磁盘上的实际分配单位是文件系统的选择。例如,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 截短了这个 测试3 编辑器中的文件:

    $ 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似乎试图在文件的物理成本方面不误导用户。这并不意味着在不了解底层文件系统实现的详细信息的情况下对计算进行反向工程是很简单的。

        2
  •  0
  •   santhosh    6 年前

    在这里,我们需要注意一件事,即数据块分配是以下面指定的方式完成的:

    1)默认情况下,为一个文件分配8个数据块,即使我们只写一个字节的数据。 在文件中。 2)当我们在文件中添加完8*4096字节的数据后,如果我们再添加一个字节,那么将再次分配新的8个数据块。 所以,总共有16个数据块。

    如果你理解上述陈述, 然后 ————(在问题中)——--- 因此,对于965,默认情况下会分配8个数据块,当它正好是4*4096=32768时,如果再添加一个字节,则会分配8个数据块,对于32769的大小,将分配16个数据块。