目录
一、初识缓冲区
缓冲区是什么?可以简单理解成一部分内存。例如用户缓冲区(char arr[])、C标准库提供的缓冲区、操作系统提供的缓冲区。
为什么要有缓冲区?要通过减少对磁盘的直接访问来提高文件操作的效率。例如给朋友寄快递,不是直接给朋友送过去,而是通过快递站,快递站也不是来一个包裹就送一个包裹,而是积累一部分包裹再统一发送,朋友只用到他对应的快递站取走包裹即可。提高了使用者的效率和发送的效率。
缓冲区能暂存数据,因此也要有一定的刷新方式。(一般策略)
- 无缓冲(立即刷新)
- 行缓冲(行刷新)
- 全缓冲(缓冲区满了,再刷新)
- 一般对于显示器文件,行刷新(行缓冲) ;对于磁盘上的文件,全缓冲(缓冲写满,在刷新)
特殊情况:
- 强制刷新
- 进程退出的时候,一般要自动刷新缓冲区,即便数据没有满足刷新条件。
强制刷新缓冲区,把当前缓冲区的内容全部刷新。类似于寄快递时对工作人员说:赶快给我发出去,不然就投诉你。这时工作人员就会把驿站当前积累的包裹都发送出去。行刷新,就是把驿站快递柜的一行快递发送。全刷新,就是驿站快递柜满了,把积累的全部包裹发送出去。
看下面一段代码思考结果如何,输出重定向到文件中,结果一样吗?
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
printf("C: hello printf\n");
fprintf(stdout, "C: hello fprintf\n");
fputs("C: hello fputs\n",stdout);
const char* str = "system call: hello write\n";
write(1,str,strlen(str));
fork();
return 0;
}
现象:直接执行程序时向显示器打印,C标准库和系统调用的函数都打印一次,但输出重定向到 log.txt 文件时,C标准库提供的函数打印两次,系统调用的函数只打印一次。
原因:
- 当我们直接向显示器打印的时候,显示器文件的刷新方式是行刷新!而且代码输出的所有字符串,都有'\n'。fork之前,数据全部已经被刷新,包括systemcall。
- 重定向到 log.txt ,本质是向磁盘文件中写入(不是显示器)