【问题标题】:stat() and block size in CygwinCygwin 中的 stat() 和块大小
【发布时间】:2025-12-14 11:15:01
【问题描述】:

我想有类似du的功能的代码。我通过使用stat() 函数进行了尝试。我了解到stat() 报告的st_blocks 是磁盘中分配的实际块号。块大小应为 512 字节,st_blocks*512 应为文件分配的字节数。但是我发现 Cygwin 环境令人困惑。首先,我使用dd 命令创建一个 8KB 的文件。

% dd if=/dev/urandom bs=4096 count=2 of=testfile
2+0 records in
2+0 records out
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.00791222 s, 1.0 MB/s

然后我对文件运行stat 命令:

% stat testfile
  File: testfile
  Size: 8192            Blocks: 8          IO Block: 65536  regular file
Device: 7727c30h/124943408d     Inode: 25614222880771065  Links: 1
Access: (0664/-rw-rw-r--)  Uid: (197881/ crystal)   Gid: (  513/    None)
Access: 2018-05-01 15:11:50.760626400 +0800
Modify: 2018-05-01 15:11:50.761626500 +0800
Change: 2018-05-01 15:11:50.761626500 +0800
 Birth: 2018-05-01 15:11:50.760626400 +0800

我认为生成的文件上没有“漏洞”。我得到分配了 8 个块的文件,这意味着块大小为 1KiB 而不是 512B。如果我用stat() 调用C 代码,st_blocks 会得到相同的结果。

到目前为止,所有文章都说块大小是 512B。有例外吗?如果是,我怎样才能得到实际的块大小?或者,如何获取文件实际占用的磁盘空间?

【问题讨论】:

    标签: filesystems cygwin stat


    【解决方案1】:

    stat 命令行工具有一个%B 格式选项,它显示它正在使用的块大小。看来stat 在 Cygwin 中使用了一个 1024 字节的块。

    此外,似乎 NTFS 4096 字节块大小实际上是在后台使用的,stat 只是呈现 1024 字节块:

    $ dd if=/dev/urandom of=foo count=1 bs=4095
    $ stat -c '%B %b' foo
    1024 4
    $ dd if=/dev/urandom of=foo count=1 bs=4097
    $ stat -c '%B %b' foo
    1024 8
    

    https://unix.stackexchange.com/questions/28780/file-block-size-difference-between-stat-and-ls 讨论了 512 字节与 1024 字节块大小的来源。显然这与 Linux 内核约定与 GNU 实用程序约定有关。

    【讨论】:

    • 谢谢。是否有系统调用可以获得块大小为stat %B
    • 我认为没有系统调用——它不是真正的内核。根据 Stack Exchange 文章,该大小是在 GNU lib 标头中设置的。