目录
一、文件fd的分配规则
最小的没有被使用的数组下标,会被分配给最新打开的文件。
二、对输出重定向现象的理解
正如上面这段代码所示,printf打印的内容并没有向显示器上打,而是输出到了log1.txt文件里面,这又是为什么呢?原因就是在该进程的文件描述符表中,原来的下标1位置存的是显示器文件的地址,你使用系统调用接口close(1),相当于把1位置的内容清空了,也就是1位置不再存储显示器文件的地址,后来你又打开了log1.txt文件,操作系统检测到你这个进程的文件描述符表中最小的没有被使用的数组下标为1,所以就把log1.txt文件的地址填入了1位置,这是在操作系统层面上做的工作。而在上层的语言层面上,stdout这个文件的文件描述符仍然为1,而且printf函数只认stdout这个文件,只会往stdout这个文件进行写入,stdout文件通过它的文件描述符在底层的文件描述符表中进行查找的时候找到1位置,而此时1位置所存放的地址已经悄悄地被改成了log1.txt文件的地址,所以printf函数的内容自然就写到了log1.txt文件中了。这就是输出重定向。下面是图解:
但上面这一段代码有一个小细节需要注意,就是你在进程结束之前不能关闭该文件。如果在进程结束之前关闭该文件,语言层面的缓冲区的内容还来不及刷新到文件中文件描述符中1位置的地址就被清空了,最后进程退出要刷新缓冲区的内容时会因为找不到文件的地址而写不到文件当中。正如下面代码和结果所示:
三、输出输入重定向的简单实现
命令行解析>符号的时候,把>符号解析成重定向,然后在底层完成重定向的工作,变相地向文件中进行写入。下面我用dup2()这个系统调用接口实现一下输出重定向和输入重定向。 dup2()这个接口是指在文件描述符中将newfd位置的地址改成oldfd位置的地址,具体实现如下所示:
1、输出重定向
fd位置的文件地址覆盖了原本1位置上的文件地址,结果就将本来应该打印到屏幕上的一串hhh字符最终输入到了指定文件当中。
2、输入重定向
fd位置的文件地址覆盖了原本0位置上的文件地址,本来应该从键盘中读到的内容最终从文件中读到了。