C 使用stat()和ls-s分配的块数不同

C 使用stat()和ls-s分配的块数不同,c,C,我试图用C获得分配给文件的块数。我使用stat struct及其名为st_blocks的变量。然而,与ls-s相比,它返回的块数不同。有人能解释一下原因吗?如果有办法纠正的话?没有差异;只是一个误会。这里有两个独立的“块大小”。使用ls-s--block size=512也可以为ls使用512字节的块大小 该命令以用户指定的单位(“块”)列出分配给文件的大小,可以使用--block size选项指定其大小 中的st_块字段以512字节为单位 您会看到差异,因为两个“块大小”不相同。他们只是碰巧

我试图用C获得分配给文件的块数。我使用stat struct及其名为st_blocks的变量。然而,与ls-s相比,它返回的块数不同。有人能解释一下原因吗?如果有办法纠正的话?

没有差异;只是一个误会。这里有两个独立的“块大小”。使用
ls-s--block size=512
也可以为
ls
使用512字节的块大小


该命令以用户指定的单位(“块”)列出分配给文件的大小,可以使用
--block size
选项指定其大小

中的
st_块
字段以512字节为单位

您会看到差异,因为两个“块大小”不相同。他们只是碰巧被叫做同一个名字

下面是一个可以检查这种效果的示例。这适用于所有POSIXy/Unixy文件系统(支持),但不适用于FAT/VFAT等

首先,让我们创建一个文件,它的长度为1兆字节,但开头有一个洞(它们读取零,但实际上没有存储在磁盘上),末尾有一个字节(我将使用
'X'

为此,我们使用
dd
跳过文件的前1048575字节(创建一个“洞”,从而在支持该文件的文件系统上创建一个稀疏文件):

我们可以使用该实用程序检查该文件。格式说明符
%s
提供文件的逻辑大小(1048576),
%b
块数(
st_块
):

在我的系统上,我得到
st_size=1048576 st_blocks=8
,因为实际的文件系统块大小是4096字节(=8×512),而这个稀疏文件只需要一个文件系统块

但是,使用
ls-s稀疏文件
我得到了
4个稀疏文件
,因为默认的ls块大小是1024字节。如果我跑

ls --block-size=512 -s sparse-file
然后我看到了
8稀疏文件,正如我所期望的那样。

这里的“块”不是真正的文件系统块。它们是便于展示的块

st_块
可能使用512字节块。看

st_blksize
是此文件的首选块大小,但不一定是实际块大小

BSD
ls-s
始终使用512字节的“块”。例如,OSX默认使用BSD ls

$ /bin/ls -s index.html 
560 index.html
GNU ls似乎使用1K块,除非用
--块大小
覆盖

$ /opt/local/bin/gls -s index.html 
280 index.html
printf(“%lld/%d\n”,buf.st_块,buf.st_块大小)产生
560/4096
。560个“块”是512字节的块,但真正的文件系统块是4k

该文件包含284938字节的数据

$ ls -l index.html 
-rw-r--r-- 1 schwern staff 284938 Aug 11  2016 index.html
…但我们可以看到它在磁盘上使用280K或70字节

请注意,OSX使用1000字节表示“千字节”,而不是正确的1024字节,这进一步混淆了这个问题,这就是为什么它使用287KB表示704096KB的块(即286720字节),而不是280KB。之所以这样做,是因为硬盘制造商开始使用1000字节的“千字节”来扩大其大小,而苹果也厌倦了客户抱怨“丢失”的磁盘空间

通过制作一个小文件可以看到4K块的大小


你能告诉我你得到了什么值吗?据曼恩说,stat使用512B块大小。也许ls使用的是另一个。您可以使用ls-s--block size=512对其进行排序并检查输出。
man 2 stat
:st_blocks是512字节块的数量。st_blocksize是底层文件系统的实际块大小。按照国际标准,以千字节为单位的1000字节是正确的。对于1024字节,有kibibyte或kiB。请不要散布错误的信息。@Ilyapov关于标准的伟大之处在于有太多的选择!您指的是SI和ISO/IEC标准十进制千字节。字节的十进制是最近的,过去10年或20年。而且,与其他十进制尝试不同,它们在字段中的结构和使用方式(即二进制)与外行理解它们的方式之间产生了冲突。这会引起很多混乱。无论如何,我认为,试图对十进制进行标准化是带宽和存储容量膨胀的结果,而不是相反。是的,我指的是SI和ISO。这对于一致性非常重要:假设我们有一个CPU,每个周期处理一个字节,运行速度为1GHz。每秒有多少千兆字节?我发现只有1GB/s是唯一合理的答案,而不是按照您的定义为0.931GB/s。(然而,我是一名物理学家。)@Ilyapov是的,它适用于时钟速度,时钟速度是频率的一种度量,本质上不是二进制的,尽管它们很少在1、2或3 Ghz甚至固定频率下运行,所以它的优势是没有意义的(我的目前在3520.0 MHz左右波动)。这对内存、存储和带宽都不是很好,它们本质上是二进制的,并且是以2的幂建立起来的。4096字节的块是真实的。引用4K块(意味着4096字节)比引用4.096K块容易得多。人们很少记得指定KiB,因为没有人使用十进制字节。
$ /opt/local/bin/gls -s index.html 
280 index.html
$ ls -l index.html 
-rw-r--r-- 1 schwern staff 284938 Aug 11  2016 index.html