输入输出重定向
输出\入重定向和追加重定向原理
什么是输出重定向
,举个例子
把hello world从键盘输入的数据输入到mylog中
把mylog中的内容输出到显示屏文件
这就是输出重定向cat+回车
同理输入重定向
,是先将0号数组中的文件关闭,再打开一个文件,以后就从该文件读取数据
cat < mylog 输入重定向,其实就是把当前cat进程里的0号fd数组里的文件(stdin)关闭,将mylog的文件放入0号数组,以后读取数据都从mylog中读取
现在我们看看这个代码
运行结果
是不是很疑惑,本应该输入到屏幕上的信息输入到了mylog里面,这是为什么呢?
首先我们关闭了文件描述符为1的文件继而打开mylog,现在mylog的文件描述符变成1,printf本该往stdout(标准输出,即屏幕)写的数据现在写入了mylog中,1里是mylog所以往mylog中写。
所以重定向的原理就是将数组里的内容发生一下变化就可以了
>>
追加重定向,每次写都比上一次多一条信息,原理
是先把1号文件描述符对应数组里的文件(stdin键盘文件关闭)
在(以追加的方式)
打开一个文件
我再来看下面一段代码
分别用printf``fwrite``write
向显示器文件写入了msg运行结果显示器显示三条信息
正确,没有毛病,但我们现在要做的事是将他fork
一下然后输出重定向到file中看看会发生什么
诶呦,怎么多了两条信息,这里我们来分析一哈
首先
printf
和fwrite
肯定是在fork之前就调用完了,往显示器上打没有问题,但重定向到文件里就出了问题,但如果在fork之前数据就写入file文件里,这样就不可能多打两次,所以真相只有一个,那就是fork之前数据并没有打印到file里,那他到哪里去了,回答正确,那就是到FILE结构体里的缓冲区里去了。
printf
在往屏幕上(stdin)
显示时很明显是行缓冲,就是一行写完后或者遇到\n
时,就将数据从FILE结构体里的缓冲区刷新到屏幕上,但
一个进程想要把数据写到文件里,数据的刷新方式将发生变化由之前的行缓冲变成全缓冲
。
全缓冲
:一个进程往文件里写数据时,当他的缓冲区写满了或者当前进程结束了,这是他才会将数据整个刷新到文件之中。现在我们可以解释为什么file里会多出来两条msgprintf往file中写数据局的时候,他会将数据先保存在缓冲区(FILE结构体里的缓冲区),程序调用fork()之后父子俩个进程发生写时拷贝,各自储存一份数据,继而进程结束,将数据刷新到file里,fwrite的原因同上。聪明的你肯定会问
write
呢,write
只打印一次,说明他并没有将数据进行缓冲,而是直接打印到了file里,很明显write是一个系统调用的接口,那你肯定会马上说fwrite和printf底层一定是调用了write,所以缓冲区是c库提供的,所以缓冲区应该放在file——struct里的缓冲区