目录
一,标准IO基本概念
二,缓冲机制
关于行缓存与缓存区的大小
通过标准IO计算缓存区大小:
IO:input/output,针对文件的输入输出。
Linux下的文件类型:
b(block块设备),
c(character字符设备),
d(directory目录),
-(普通文件),
l(line链接文件),
s(socket套接字文件),
p(pipe管道);
1.概念:在C库中定义的一组专门用于输入输出的函数。
2.特点:
(1)标准IO通过缓冲机制减少系统调用的次数,从而提高效率。
(2)标准IO围绕“流”进行操作,流使用“ FILE * ”描述,“ FILE * ”->一个结构体指针。
(3)标准IO默认打开三个流:stdin(标准输入),stdout(标准输出),stderr(标准出错)。
系统调用:内核向上提供的一层函数接口。
3.ctags追踪代码
例:查看FILE的代码。
命令:在终端输入vi -t FILE
回车后进入以下界面后,输入1,然后回车:
光标自动位于48行开头,可以看出FILE是结构体_IO_FILE重定义后的结构体名;
然后将光标置于_IO_FILE处,按下"Ctrl+]",终端底部将会出现以下界面:
输入1后回车,就可以看到有关结构体_IO_FILE的详细代码:
Ctrl+t可以回退到上一界面;
缓冲机制分为三种,分别是全缓存,行缓存和不缓存,重点介绍和使用行缓存。
1.全缓存
全缓存与文件相关,刷新缓存区有三个条件:
①程序正常退出时刷新;
②缓存区满刷新;
③强制刷新:fflush函数;
2.行缓存
行缓存与终端相关,刷新行缓存有四个条件:
①‘\n’可以刷新;
②程序正常退出时刷新;
③缓存区满刷新;
④强制刷新:fflush函数;
3.不缓存
不缓存即没有缓存区,一般是标准出错stderr,因为程序出错时,我们希望它及时显示在终端上,而不是保存在缓存区;
分析以下代码:
#include
int main(int argc, const char *argv[])
{
printf("hello");
while(1);
return 0;
}
程序运行后,光标一直停止在行首闪烁,不会输出字符串hello;
我们尝试三种方式来刷新缓存区:
(1)使用\n刷新缓存区:
#include
int main(int argc, const char *argv[])
{
printf("hello\n");
while(1);
return 0;
}
程序运行后,会先输出字符串hello,然后光标在字符串的下一行行首不断闪烁;
(2)缓存区满刷新:
#include
int main(int argc, const char *argv[])
{
for(int i = 0;i < 300;i++)
{
printf("%04d",i);
}
while(1);
return 0;
}
我们可以通过缓存区满刷新的特点来计算缓存区的大小,程序执行后,每输出一个数字,该数字都占4位,不够4位以0补全,从0输出到255,一共输出了256个数字,缓存区大小即256*4,1024个字符大小,但是这种方法比较麻烦;
使用标准IO计算缓存区大小时,应该先使用缓存区,然后再计算;
#include
int main(int argc, const char *argv[])
{
printf("hello\n");//必须先使用缓存区,然后进行缓存区大小计算
printf("%d\n",stdout->_IO_buf_end - stdout->_IO_buf_base);
return 0;
}
stdout相当于FILE *,也就是FILE的结构体指针,buf指缓冲区;
程序执行后,先输出字符串hello,然后在下一行输出缓存区大小1024;
(3)强制刷新fflush:
#include
int main(int argc, const char *argv[])
{
printf("hello");
fflush(NULL);
while(1);
return 0;
}
程序执行后,先输出hello,然后光标在hello的下一位持续闪烁;
如果本文中存在代码逻辑,代码完善,概念解释不通或不清楚的错误,请批评指正。