Linux——文件描述符fd的理解(进程,系统调用函数,文件流指针)

时间:2024-04-05 20:21:32

1.概念

在linux下一切皆文件,文件描述符是内核为了高效的管理已经被打开的文件所创建的索引,它是一个非负整数,用于指代被打开的文件,所有执行I/O操作的系统调用都是通过文件描述符完成的。而系统调用函数open的返回值就是文件描述符-fd。

2.与系统调用函数(opem,read ,write,close,lseek)的关系

int open(const char *pathname,int flags,mode_t mode);

  • pathname :要打开的文件名称(路径+名称)
  • flags :以何种方式打开
  • 必须的宏,三个宏有且只能出现一个
  • O_RDONLY :只读方式
  • O_WRONLY : 只写方式
  • O_RDWR :读写方式可选的宏
    O_APPEND :追加
    O_TRUNC :截断
    O_CREAT :文件不存在则创建
    使用的方式,必须的宏和可选的宏之间使用按位或的方式eg: O_RDWR | O_CREAT
  • mode :权限
    新创建出来的文件设置权限
    传参的时候,传递8进制数字就可以了
  • 返回值:
    打开成功,返回大于等于0的数字,是文件描述符打开失败,返回-1

ssize_t read(int fd,void *buf,size_t count) :

  • fd :文件描述符,open的返回值
  • buf :要将读到的内容放到哪里去
  • count :最大可以读多少个,单位字节返回值:返回读到的字节数量

ssize_t write(int fd,const void *buf,size_t count);

  • fd :文件描述符,open的返回值
  • buf :往文件当中写的内容
  • count :写的内容的大小返回值:写成功的字节数量

off_t lseek(int fd, off_t offset,int whence) ;

  • fd :文件描述符
  • offset :偏移量whence :
  • whence:SEEK_SETSEEK_ CURSEEK_END

int close(int fd) ;

  • 关闭文件描述符

因此很明显看出来,上述几个函数就是通过文件描述符找到对应的文件进行操作的

3.创建进程时的三个默认的文件描述符

  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器

4.文件描述符与进程之间的关系

Linux——文件描述符fd的理解(进程,系统调用函数,文件流指针)

  1. 文件描述符实际上是内核中文件描述信息表中数组下标,用户根据下标在进程pcb中的文件描述信息表中找到相应文件描述信息,实现对文件的操作;
  2. 文件描述符就是从0开始的小整数
  3. 我们打开文件时,会创建一个file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向files_struct,该表包涵一个指针数组,每个元素都是一个指向打开文件的指针

4.文件描述符分配规则

文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。

5.文件描述符与文件流指针的关系

  1. 文件流指针是fopen函数返回的,是库函数,由C库进行维护
  2. 文件描述符是open函数返回,是系统调用函数,由内核进行维护

Linux——文件描述符fd的理解(进程,系统调用函数,文件流指针)

  1. 不同的文件流指针,在C库的当中当中会创建不同的struct _IO_FILE,在_IO_FILE结构体当中保存了不同的文件描述符
  2. 文件流指针当中包含文件描述符
  3. 操作系统当中广泛存在缓冲区,但是如果针对文件流指针而言的缓冲区,是C库在维护的
  4. exit函数在退出的时候,会刷新缓冲区,就是因为操作的是文件流指针。_exit函数在退出一个进程的时候,不会刷新该缓冲区,是因为该缓冲区是C库在维护的,内核并不知道,所以不会刷新。