Linux:文件、fd

Linux:文件、fd

  • 前言
  • 一、C语言中常见打开文件的函数接口
  • 二、打开文件的系统调用接口
  • 三、文件描述符fd
  • 四、为何Linux下一切皆文件

前言

文件 = 内容 + 属性

 所有对文件的操作本质上就分为:对内容的修改对属性的修改
 内容是数据,属性也是数据。所以存储文件,必须同时存储文件相关的数据信息和属性信息。默认情况下文件存储在磁盘中,但由于冯诺依曼体系,CPU只能从内存中获取文件信息,对文件进行操作。所以当进程打开文件时,OS需要先将文件信息加载到内存中,在被CPU调度执行对文件进行操作!!

 一个进程可以打开多个文件,多个进程也可以打开同一个文件。所以当文件被加载到内存时,被打开的文件可能存在多个。操作系统需要对这些文件进行管理。先组织在描述!!OS会在内核数据结构中,为所有被打开的文件形成一个结构体对象。最后将所有文件结构体对象通过链表的形式链接起来,从而将对文件的管理转化为对该链表的增删查改!!

 文件按照是否被打开分为:被打开的文件(在内存中)、没有被打开的文件(磁盘中)。所以文件操作的本质就是:进程和打开文件的关系!!

一、C语言中常见打开文件的函数接口

 C语言中,打开文件的函数接口如下:

FILE *fopen(const char *path, const char *mode);

 文件打开方式:

 r Open text file for reading. The stream is positioned at the beginning of the file.r+ Open for reading and writing.The stream is positioned at the beginning of the file.w Truncate(缩短) file to zero length or create text file for writing.The stream is positioned at the beginning of the file.w+ Open for reading and writing.The file is created if it does not exist, otherwise it is truncated.The stream is positioned at the beginning of the file.a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.a+ Open for reading and appending (writing at end of file).The file is created if it does not exist. The initial file positionfor reading is at the beginning of the file, but output is always appended to the end of the file.
  • w方式打开,会先清理文件内容。
  • a方式打开,不会清理文件内容,直接在文件内容后追加新内容。

二、打开文件的系统调用接口

 进程打开文件,只能通过OS去打开文件。所以操作系统会为我们提供一些打开文件的系统调用接口!!
(也从侧面说明C库函数一定封装了这些系统调用接口)

 下面我们来看看操作系统都提供了哪些系统调用接口吧!

 #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);int creat(const char *pathname, mode_t mode);//不介绍, 和open类似,但只能以w方式打开
  1. 返回值int是文件描述符fd,类似于C语言中的FILE(真实情况是FILE中封装了fd)。创建失败时,返回-1。

  2. flags:打开文件操作时选择的标记位。正常情况下,标记位为两态的数据,即0、1。所以我们可以通过flag整型的不同比特位表示不同的标记位。最后通过按位或的方式,将所有选择的标记位结合起来。从而通过一个变量传递多个标记位!!

常见标记位:

 O_RDONLY//只读方式打开 O_WRONLY//写的方式打开O_RDWR//读写方式打开O_CREAT//文件不存在,创建文件O_TRUNC//截断清空,主要用于只读方式打开时,需要先将文件内容清空O_APPEND//追加的方式打开
  1. mode:新创建的文件默认要受Linux权限控制。如果没有指定权限,新创建的文件权限发生乱码!
  int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC);         if(fd < 0)    {    perror("open");    return 1;    }    close(fd);     

【创建文件权限乱码】:
在这里插入图片描述
【正确创建方式】:

  int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);         if(fd < 0)    {    perror("open");    return 1;    }    close(fd);   

在这里插入图片描述

  • 文件以666权限创建,最终结果为664。是由于文件掩码的存在,也可通过umask系统调用接口更改文件创建的权限掩码。但不推荐,通常和系统默认掩码保持一致!!

三、文件描述符fd

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

那文件描述符fd这的数字都表示什么?
 操作系统需要对文件进行管理,在Linux中,OS会为每一个被打开的文件形成对应的描述结构体对象(Linux中被称为struct file)并且操作系统会将所有被打开文件的描述结构体对象通过链表形式链接起来。

 但每一个进程可能打开多个文件,多个进程可能打开同一个文件。并且操作系统不希望每个管理模块间耦合度过大。所以操作系统为了让进程和对应的打开文件关联起来,操作系统会在进程的PCB中维护一个结构体指针(struct files_struct*),该指针指向一张进程文件描述符表(files_strict),该表中包含一个指针数组,每个元素都是指向被打开文件的函数指针。因此,文件描述符表本质上就是该数组中指向对应文件的元素下标!!!

在这里插入图片描述

四、为何Linux下一切皆文件

 计算机所有的底层硬件的读写方式都是不一样的,但是操作系统为了管理这些硬件也会和文件一样,生成对应的描述结构体对象(struct file)。而在所有的文件结构体中,都包含文件的读指针(read*)、写指针(write*)。对不同硬件的读写,都可以通过结构体对象中的读指针和写指针指向底层不同的硬件各自读写方式。

&emap;尽管不同硬件的读写方式不同,但操作系统为了管理会为我们抽象一层软件层。对于上层用户来说,不管是对硬件还是文件的读写操作,本质上都和控制文件一样,调用struct file结构体对象中的读写指针。所以Linux下一切皆文件!!!

 我们也将该软件层称为文件虚拟系统(VFS)。这是是多态技术的来源之一!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/705993.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP_ABAP-思考篇

作为一个SAP十年左右的从业者&#xff0c;其实我很清楚&#xff0c;我自身的能力&#xff0c;确实是很多东西都会一点&#xff0c;但是没有一样是精通的。坦白来说&#xff0c;我的个人简介里&#xff0c;虽然也不算夸大&#xff0c;但我估计有些新手小白看着可能会觉得还挺厉害…

windows驱动开发-PCI讨论(一)

前面描述中断的时候&#xff0c;我们曾经多次体积PCI&#xff0c;甚至提供了一些PCI的相关知识&#xff0c;但是整个PCI是一个很大的体系&#xff0c;专门记录这个体系超出了这个系列的范畴&#xff0c;有兴趣的可以到PCI官网了解详细的情况。 但是还是会花费一些时间讨论PCI技…

大模型时代下的先行者:景联文科技引领数据标注新时代

在大模型时代&#xff0c;数据标注不再是简单的分类标注&#xff0c;而是一项融合了技术革新、专业技能、法律合规和精细化管理的综合性任务&#xff0c;对推动AI技术的发展和落地应用具有重要意义。 景联文科技作为AI基础行业的数据供应商&#xff0c;可协助人工智能企业解决整…

【Python】图像批量合成视频,并以文件夹名称命名合成的视频

一个文件夹中有多个子文件夹&#xff0c;子文件夹中有多张图像。如何把批量把子文件夹中的图像合成视频&#xff0c;视频名称是子文件夹的名称&#xff0c;生成的视频保存到指定文件夹&#xff0c;效果记录。 代码 import os import cv2def create_video_from_images(image_f…

电路板维修【四】

【开关电源输出电压偏低不稳&#xff0c;用示波器立马锁定故障范围】&#xff1a;https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏&#xff1a; 电源芯片的供电电压来回跳变&#xf…

【Linux线程(三)】生产者消费者模型

目录 前言&#xff1a; 一、什么是生产者消费者模型 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;321原则 1.三个关系 2. 两种角色 3.一个场所 &#xff08;三&#xff09;生产者消费者模型的优缺点 二、基于阻塞队列实现生产者消费者模型 &#xff0…

yolov8 模型架构轻量化 | 极致降参数量

模型轻量化加速是深度学习领域的重要研究方向&#xff0c;旨在减小模型的体积和计算复杂度&#xff0c;从而提高在资源受限设备上的运行效率&#xff0c;模型参数量在轻量化加速中扮演着至关重要的角色。 首先&#xff0c;模型参数量直接决定了模型的复杂度和存储空间需求。随…

HNU-算法设计与分析-作业6

第六次作业【分支限界法】 文章目录 第六次作业【分支限界法】<1> 算法实现题6-2 最小权顶点覆盖问题<2> 算法实现题6-6 n后问题<3> 算法实现题6-7 布线问题 <1> 算法实现题6-2 最小权顶点覆盖问题 ▲问题重述 问题描述&#xff1a; 给定一个赋权无向…

【SQL】SQL常见面试题总结(3)

目录 1、聚合函数1.1、SQL 类别高难度试卷得分的截断平均值&#xff08;较难&#xff09;1.2、统计作答次数1.3、得分不小于平均分的最低分 2、分组查询2.1、平均活跃天数和月活人数2.2、月总刷题数和日均刷题数2.3、未完成试卷数大于 1 的有效用户&#xff08;较难&#xff09…

C++ I/O流(一)——输出流

一、IO流概念 IO流可分为输入流和输出流,用于从设备(如键盘、文件、网络等)读取数据或向设备写入数据。C++标准库提供了丰富的IO流类,包括iostream、fstream、stringstream等,分别用于处理控制台输入输出、文件输入输出和字符串流操作。 读操作:输入流中读取数据到程序中…

Spring Boot | SpringBoot 中 自定义 “用户授权管理“ : 自定义“用户访问控制“、自定义“用户登录控制“

目录: 一、SpringBoot 中 自定义 "用户授权管理" ( 总体内容介绍 ) :二、 自定义 "用户访问控制" ( 通过 "HttpSecurity类" 的 authorizeRequests( )方法来实现 "自定义用户访问控制" ) :1.基础项目文件准备2.实现 "自定义身份认…

论文阅读-《MHFormer: Multi-Hypothesis Transformer for 3D Human Pose Estimation》

目录 1 摘要 2 介绍 3 相关工作 3.1 3D HPE 3.2 ViT 3.3 多假设方法 4 MHFormer 4.1 概述 4.2 准备阶段 4.2.1 多头自注意力机制&#xff08;MSA&#xff09; 4.2.2 多层感知器&#xff08;MLP&#xff09; 4.3 MHG-多假设生成 4.3.1 概述 4.3.2 详细解释&#x…