我试图使用C来获取分配给文件的块数。我使用了stat结构及其变量st_blocks。然而,与ls -s相比,这返回了不同数量的块。任何人都可以解释这个原因以及是否有办法纠正这个问题?
答案 0 :(得分:2)
没有差异;只是一个误会。这里有两个单独的“块大小”。使用ls -s --block-size=512
也可以使用ls
的512字节块大小。
ls -s
命令以用户指定的单位(“块”)列出分配给文件的大小,您可以使用--block-size
选项指定大小。
struct stat
中的st_blocks
字段以512字节为单位。
您会看到差异,因为两个“块大小”不一样。它们碰巧被称为同名。
以下是您可以检查此效果的示例。这适用于所有POSIXy / Unixy文件系统(支持sparse file),但不适用于FAT / VFAT等。
首先,让我们创建一个但是一兆字节长的文件,但在开头有一个洞(它们读取零,但实际上并不存储在磁盘上),最后只有一个字节(我将使用{{ 1}})。
我们通过使用'X'
跳过文件的第一个1048575字节(创建“漏洞”,因此在支持此类文件系统的文件系统上的稀疏文件)来执行此操作:
dd
我们可以使用stat
实用程序来检查文件。格式说明符printf 'X' | dd bs=1 seek=1048575 of=sparse-file count=1
提供文件的逻辑大小(1048576),%s
块的数量(%b
):
st_blocks
在我的系统上,我得到stat -c 'st_size=%s st_blocks=%b' sparse-file
,因为实际的文件系统块大小是4096字节(= 8×512),而这个稀疏文件只需要一个文件系统块。
但是,使用st_size=1048576 st_blocks=8
我得到ls -s sparse-file
,因为默认的ls块大小是1024字节。如果我跑
4 sparse-file
然后我看到了ls --block-size=512 -s sparse-file
,正如我所料。
答案 1 :(得分:2)
这里的“块”不是真正的文件系统块。它们是方便显示的块。
st_blocks
正在使用可能 512字节块。请参阅the POSIX spec。
st_blksize
是此文件的首选块大小,但不一定是实际的块大小。
BSD ls -s
总是使用512字节“块”。例如,OS X默认使用BSD ls。
$ /bin/ls -s index.html
560 index.html
GNU ls似乎使用1K块,除非用--block-size
覆盖。
$ /opt/local/bin/gls -s index.html
280 index.html
printf("%lld / %d\n", buf.st_blocks, buf.st_blksize);
生成560 / 4096
。 560“块”是512字节块,但真正的文件系统块是4k。
该文件包含284938个字节的数据......
$ ls -l index.html
-rw-r--r-- 1 schwern staff 284938 Aug 11 2016 index.html
...但我们可以看到它在磁盘上使用280K或70字节。
请注意,OS X通过使用1000字节表示“千字节”而不是正确的1024字节来进一步混淆问题,这就是为什么它说70个4096 KB块(即286720字节)而不是280 KB的287 KB。之所以这样做是因为硬盘驱动器制造商开始使用1000字节“千字节”来扩大其规模,而Apple厌倦了抱怨“丢失”磁盘空间的客户。
通过制作一个小文件可以看到4K块大小。