文件底层的深入理解之文件输入输出重定向

简介: 文件底层的深入理解之文件输入输出重定向

目录

一、文件fd的分配规则

二、对输出重定向现象的理解

三、输出输入重定向的简单实现

1、输出重定向

2、输入重定向


一、文件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位置上的文件地址,本来应该从键盘中读到的内容最终从文件中读到了。

相关文章
|
2月前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
存储 缓存 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
|
7月前
|
容器
这个错误是因为在读取文件时,管道已经结束
【1月更文挑战第14天】【1月更文挑战第67篇】这个错误是因为在读取文件时,管道已经结束
114 4
|
7月前
|
网络协议 Shell
使用输入输出重定向与管道命令——重定向
使用输入输出重定向与管道命令——重定向。
58 0
|
存储 C++
重定向输入输出freopen,文件流fstream
重定向输入输出freopen,文件流fstream
|
编译器 数据库 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(上)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(上)
|
存储 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)
|
编译器 C++ iOS开发
C++文件操作解析及使用(读、写文件 使用文件指针)
C++文件操作解析及使用(读、写文件 使用文件指针)
282 0
C++文件操作解析及使用(读、写文件 使用文件指针)
|
Java
I/O流常用复制和读写文件
I/O流常用复制和读写文件
125 0
读取文件结束的判定的概念,使用方法和文件缓冲区的位置
读取文件结束的判定的概念,使用方法和文件缓冲区的位置
138 0
下一篇
DataWorks