我正在阅读Unix 编程环境(1984)。在第 7 章(Unix 系统调用)中,作者指出:
虽然要读取或写入的字节数不受限制,但最常用的值是 1,这意味着一次一个字符...,以及光盘上块的大小,最常见的是 512 或 1024 字节。(<stdio.h> 中的参数 BUFSIZ 具有该值。)
我写了一个简单的程序来检查这一点:
#include <stdio.h>
int main()
{
printf("The BUFSIZ is %d\n", BUFSIZ);
return 0;
}
在我的系统(Linux Mint)上返回8192。这比书中提到的“512或1024”要多得多。我认为这一定是基于历史环境的差异。
出于好奇,我在不编写自己的 C 程序的情况下查找了其他找到此块大小的方法,并发现了blockdev
.它告诉我这一点:
me@mint:~/src/c/unixprogenvbk$ sudo blockdev --getbsz /dev/sda1
4096
为什么 BUFSIZ 值为 8192 时却是 4096?这实际上是两个不同的东西吗?
答案1
我不确定该段落来自什么Unix 编程环境确实意味着,但我认为BUFSIZ
与磁盘块大小无关——这是不可能的,BUFSIZ
是一个常量,您可以在不同的磁盘上有不同的块大小(一些设备,如 NVMe 和 NVDIMM 甚至支持更改块大小) 。
我喜欢这个定义glibc 文档更多的:
该宏的值是一个整型常量表达式,适合用作 setvbuf 的大小参数。该值保证至少为 256。 BUFSIZ 的值根据每个系统进行选择,以便提高流 I/O 效率。因此,在调用 setvbuf 时,最好使用 BUFSIZ 作为缓冲区的大小。
但stdio.h
其中BUFSIZ
只是设置为 to 的常量8192
,我不确定为什么文档说它是为每个系统选择的。
blockdev
使用BLKBSZGET
ioctl 获取指定设备的块大小,因此它是磁盘的实际块大小。