【Linux系统】文件fd

发布时间:2023年12月30日

一.预备知识

  1. 文件=内容+属性
  2. 进程如果想要访问文件,必须先打开文件,即先将其加载到内存,这个工作由操作系统完成
  3. 一个进程可以打开多个文件,多个进程可以打开多个文件
  4. 操作系统要想对这么多打开的文件进行管理,必须“先描述,再组织”

最终结论:进程打开文件,操作系统会先将磁盘上的文件加载到内存,然后形成文件对象(struct file),用文件的属性填充这个结构体,然后以链表等数据结构将若干个struct file组织起来,这样就实现了对打开文件的管理

?文件可以分为未被打开的文件和打开的文件,前者在磁盘上,后者被加载到内存,本文研究的是打开的文件和进程之间的关系

二.系统调用接口open

man 2 open?

pathname:带路径的文件名,如果没带路径就在当前工作目录下查找

flags:打开方式,使用系统提供的宏,用按位或组合它们

常用的宏:

O_WRONLY:只读

O_RDONLY:只写

O_RDWR:读写

O_CREAT:文件不存在就创建

O_TRUNC:清空文件内容

O_APPEND:在文件尾部追加写入?

mode:如果创建了新文件,文件的最终权限是mode和权限掩码的合成

例如:

open("log.txt", O_WRONLY | O_CREAT | O_TRUNC) 等价于fopen("log.txt", "w")

open("log.txt", O_WRONLY | O_CREAT | O_APPEND) 等价于fopen("log.txt", "a")

三.文件描述符fd

open的返回值是什么?

操作系统管理众多的struct file以达到管理打开文件的目的,操作系统如何得知哪些文件是哪个进程打开的呢?

?实际上,进程PCB中有一个struct files_struct,其中记录了该进程打开的所有文件。?这个结构体中有一个struct file* fd_array指针数组,叫做文件描述符表,每个存储单元可能是NULL,也可能存放着指向文件对象struct file的指针。

当一个文件被open时,操作系统形成struct file结构体,然后在进程的文件描述符表中按顺序查找,如果遇到空的存储单元,就将struct file的指针存起来,然后将数组下标返回给上层,这个下标就是该文件的文件描述符fd,进程通过fd在文件描述符表中找到struct file指针,进而访问相应的文件。

验证如下:

?open返回的文件描述符依次递增,3,4,5就是文件对象指针在文件描述符表中的下标。

那么为什么不是从0开始递增呢?0,1,2放了什么呢?

四.C语言的文件指针FILE*与fd的关系

C语言程序默认打开三个文件流:标准输入流(stdin),标准输出流(stdout),标准错误流(stderr)。文件流指的就是FILE*,它是C语言操作文件的标识符。但是操作系统是只认识fd的,所以FILE结构体中封装了fd。

Linux下一切皆文件。stdin指向的FILE中封装了标准输入文件(键盘)的文件描述符0,stdout指向的FILE中封装了标准输出文件(显示器)的文件描述符1,stderr指向的FILE中封装了标准错误文件(stderr)的文件描述符2。数组的0,1,2三个下标已经被占据了,所以新的struct file*只能从3开始放了。

文章来源:https://blog.csdn.net/weixin_74113106/article/details/135286591
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。