Linux——文件基础IO的文件描述符和重定向实现理解

文章详细介绍了Linux中文件的打开和重定向操作,包括使用open函数同时打开多个文件,以及通过关闭标准流和使用dup2()函数实现重定向。此外,还讨论了符号重定向,如>、>>和<的用法。内容涵盖了文件描述符的分配规则和文件与进程的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 目录

  前言:

首先来回顾一下open函数,即在进程中同时打开多个文件:

Linux底层进程与文件的关系 :

二.重定向的实现

 什么是重定向?

 方法1:

         2.1关闭stdin:

        运行结果: 

        ​编辑由结果知:fd1指向文本文件cyq.txt,原本fd1是默认被fd_array[2]指向的,现在fd1却被fd_array[0]指向了。

        2.2关闭stderr

         运行结果:

        2.3关闭stdout :

        查看该文件cyq.txt:

         运行结果:​编辑

        总结:

方法2:

        2.4重定向函数dup2()的学习

        2.4.1函数作用:

        2.4.2.参数

        2.4.3返回值问题: 

        2.4.4案例——输出重定向:一般用于写内容到指定的地方

                运行结果:

                 运行结果:

                一次运行:

                二次运行:

                2.4.6输入重定向案例:一般用于从指定的地方读取内容。

                 运行结果:​编辑

方法3:符号形式的重定向—— “ > ” 、 “ >> ”、“ < ”

        2.5.1 符号 “ > ”    ——输出重定向符号

        实验案例:该案例将围绕123.txt文件内容为中心理解符号形式的重定向实现

                ​编辑

        2.5.2 符号“ >> ” ——追加重定向

案例:

         2.5.3符号 “ <” ——输入重定向


  前言:

        之前,我讲解了Linux下文件的特性、讲解了关于Linux关于文件的系统调用函数open、write、read、close函数,讲解了它们与C语言库中fopen、fclose、fgets、fputs等函数的区别,其实fopen、fclose、fgets、fputs这些函数是在Linux系统调用函数的底层原理下封装形成的优化C库函数。

 Linux文件基础IO的理解1   

接下来,我将继续深入讲解Linux中文件的一些底层知识。

首先来回顾一下open函数,即在进程中同时打开多个文件:

   #include<errno.h>
   #include<sys/types.h>
   #include<sys/stat.h>
   #include<fcntl.h>
   #include<stdlib.h>
   #include<unistd.h>
   
   #define Filename1 "big1.txt"
  #define Filename2 "big2.txt"
  #define Filename3 "big3.txt"
  #define Filename4 "big4.txt"
  
  
  int main(){
        //同时打开多个文件
      int f1=open(Filename1,O_CREAT| O_WRONLY |O_TRUNC,0664);
      int f2=open(Filename2,O_CREAT| O_WRONLY |O_TRUNC,0664);
      int f3=open(Filename3,O_CREAT| O_WRONLY |O_TRUNC,0664);
      int f4=open(Filename4,O_CREAT| O_WRONLY |O_TRUNC,0664);
 
    //打印这些文件描述符的值
      printf("f1: %d\n",f1);
      printf("f2: %d\n",f2);
      printf("f3: %d\n",f3);
      printf("f4: %d\n",f4);                                                          
  
      close(f1);
      close(f2);
      close(f3);
      close(f4);
      return 0;
    }

运行结果:

        从结果中,我们看到这4个文件描述符的值分别是3-6,那么有人会想为什么是从3开始往后呢?为什么不是从1开始,或者从0开始呢?

        其实这就要说到标准流了! 我们在学C语言的过程中,相必从书中就已经了解到了多种流,它们分别是标准输入流stdin、标准输出流stdout、标准错误流stderr,这三种流分别对应键盘、显示器、显示器。stdin标准输入流就是通过键盘向计算机中写入数据的;stdout标准输出流是通过读取计算机中的正常运行得出的数据到显示器中,方便查看的;stderr标准错误流是读取计算机在运行过程中产生的错误信息到显示器中。

        Linux下一切皆文件,那么这三个流也不例外,它们也是文件,而且它们三个是处于一直被打开的状态,因为每个进程的运行都离不开它们几个,于是stdin、stdout、stderr所代表的也是文件描述符,每个进程都有一个文件描述符表,它相当于一个数组,专门用于存放该进程打开的各个文件。这三个文件描述符就占据了数组的榜一榜二榜三位置,导致后面被进程打开的文件只能从数组索引位置3开始!

求证一下:

 结果运行:

Linux底层进程与文件的关系 :

 

       每个进程都有一个task_struct的结构体,该结构体中存放着该进程的各个属性,既然一个进程打开了多个文件,那么这几个被该进程打开的文件就必须要被管理和维护,所以task_struct的进程属性中就又多了一个属性:file_struct* files指针,该指针指向记录着该进程所打开的所有文件的结构体:files_struct。

        Linux下一切皆文件的本质和 “先描述,再组织 ” 的核心管理理念,使得我们能够清楚的了解到这个结构体中包含着每个被打开文件的各个属性,其中的成员file* fd_array[ ]指针数组便是存放着文件的各个文件描述符。所以本质上,文件描述符就是指针数组的下标。所以进程和被打开文件的关系就是通过文件描述符表files_struct映射的。

二.重定向的实现

        

 什么是重定向?

         重定向就是说改变数据的流向!举个例子大家就明白了:有一家厂商给超市供大量货物时,由于厂商偷工减料赚黑心钱,被超市发现后立即停止该家厂商继续供货,另外寻找其他厂商商量超市货物供应。这就是重定向,在原本的基础数据流程方向上进行转换,重新选择新的数据流程方向。

        重定向的实现共有三种方式,其中两种是需要在程序中使用代码去实现重定向,还有一种就是直接使用>、>>、<符号去实现重定向。

方法1:

        既然stdin,stdout,stderr这三个流的类型也是文件,那么意味着它们可以被close,假如我们关闭了file* fd_array[ ]数组中的前3个标准流,会发生什么?

2.1关闭stdin:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main(){
    close(0);     //关闭stdin流
    int fd1=open("cyq.txt",O CREAT O WRONLY O TRUNC,0666);
        if(fd1<0){
            perror("open");
            exit(-1);
            }
    printf("open fd1: %d\n", fd1);
    close(fd1);
    return 0;
    }

        由上面代码可知:关闭了文件描述符表中数组的首元素,意味着fd_array[0]不再指向stdin——键盘,那么该数组的首元素为空。 

运行结果: 


由结果知:fd1指向文本文件cyq.txt,原本fd1是默认被fd_array[2]指向的,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙予清的zzz~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值