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 position
 for 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)。这是是多态技术的来源之一!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web自动化系列-使用普通模式编写测试用例以及存在问题(十六)

前面已经把selenium的主要操作介绍完毕 &#xff0c;接下来我们通过编写几条测试用例感受下selenium的用法 。 1.用例需求 还是以登录为例 &#xff0c;需要实现的测试用例为 &#xff1a; case1&#xff1a;输入正确的用户名和密码进行登录case2 : 输入正确的用户名和错误的…

小红书“脆皮”用户健康研究报告

人均脆皮、血脉觉醒、爆肝打工、脱发危机……各式各样的健康议题不断被推上生活舞台&#xff0c;年轻人纷纷自嘲&#xff1a;“20多岁的年纪&#xff0c;却有了60多岁的身体”。 近年&#xff0c;大健康行业欣欣向荣&#xff0c;小红书成为大众分享健康生活的聚集地&#xff0c…

Python 小抄

Python 备忘单 目录 1.语法和空格 2.注释 3.数字和运算 4.字符串处理 5.列表、元组和字典 6.JSON 7.循环 8.文件处理 9.函数 10.处理日期时间 11.NumPy 12.Pandas 要运行单元格&#xff0c;请按 ShiftEnter 或单击页面顶部的 Run&#xff08;运行&#xff09;。 1.语法和空格…

关于 vs2019 c++20 规范里的一个全局函数 _Test_callable

&#xff08;1&#xff09;看名思议&#xff0c;觉得这个函数可以测试其形参是否是可以被调用的函数&#xff0c;或可调用对象&#xff1f; 不&#xff0c;这个名字不科学。有误导&#xff0c;故特别列出。看下其源码&#xff08;该函数位于 头文件&#xff09;&#xff1a; 辅…

50.乐理基础-拍号的类型-混合拍子

混合拍子的定义&#xff1a; 1.由不同的单拍子组合起来的&#xff0c;如图1。 2.因为组合顺序有多种可能&#xff0c;所以次强拍的位置也有多种可能&#xff0c;如图3。 图1&#xff1a;四二拍是单拍子&#xff0c;四三拍也是单拍子&#xff0c;四二拍 与 四三拍就是 不同的单拍…

Google Ads被暂停的原因,如何防范?

跨境出海业务少不了需要做Google Ads推广业务&#xff1b;其中让投手们闻风丧胆的消息就是帐户被暂停。当 Google 检测到任何违反其政策且可能损害用户在线体验的行为时&#xff0c;就会发生这种情况。那么如何在做广告推广的同时&#xff0c;保证账号不被封禁呢&#xff1f;看…

59.基于SSM实现的网上花店系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;网上花店是在MySQL中建立数据表保存信息&#xff0c;运用SSMVue框架和Java语言编写。并按照软件设计开发流程进行设计实现充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SSM的网…

Springboot+MybatisPlus如何实现带验证码的登录功能

实现带验证码的登录功能由两部分组成&#xff1a;&#xff1a;1、验证码的获取 2、登录&#xff08;进行用户名、密码和验证码的判断&#xff09; 获取验证码 获取验证码需要使用HuTool中的CaptchaUtil.createLineCaptcha()来定义验证码的长度、宽度、验证码位数以及干扰线…

算术平均数

算术平均数&#xff08;average&#xff09;是一组数据相加后除以数据的个数而得到的结果&#xff0c;是度量数据水平的常用统计量&#xff0c;在参数估计和假设检验中经常用到。比如&#xff1a;用职工平均工资来衡量职工工资的一般水平&#xff0c;用平均体重来观察某一人群体…

uac驱动之const修饰的变量和const修饰的指针

const int*p // p所指向的空间是常量 不可修改 ,但p可以修改 int*const p // p所指向的空间是可以修改 ,p不可以修改 #include <stdio.h> #include <string.h>struct usb_string {char id;const char *s; };enum {STR_ASSOC,STR_AC_IF,STR_USB_OUT_IT,STR_USB_O…

4种企业防泄密的办法,强烈推荐第二种

4种企业防泄密的办法&#xff0c;强烈推荐第二种 企业信息泄密常见的原因有内部人员、黑客、违规收集信息、第三方合作商&#xff0c;以下将为你详细分析这些泄密原因以及应对的方法。 1、内部人员泄密 内部员工由于能够接触到敏感数据&#xff0c;成为主要的泄露数据群体。这…

2024年中国国际厨卫家居展览会(上海KIB厨卫展)

中国国际厨卫家居博览会&#xff08;KIB&#xff09;由中国五金制品协会、中国国际贸易促进委员会轻工行业分会、北京奥维云网大数据科技股份有限公司主办。从最初的“中国国际橱柜、厨房卫浴产品与技术博览会(CIKB&#xff09;”&#xff0c;到2001年与中国国际五金展&#xf…

【React】 打包扫描出现高风险文件 YUI 版本太低 JSEncrypt

漏洞定位 扫出漏洞的情况&#xff0c;多是在说下面几个工具&#xff1a; jquery js-cookie jsencrypt 参考链接 YUI:2.9.0 (Link) http://www.cvedetails.com/cve/CVE-2012-5883/ 1.于是在打包后的代码中搜索 YUI&#xff08;不区分大小写&#xff0c;不进行全字匹配&…

数据结构初阶 顺序表的补充

一. 题目的要求 写出三种链表的接口函数 它们的功能分别是 1 查找数的位置 2 在pos位置插入值 3 在pos位置删除值 二. 实现pos 这个其实很简单 找到一步步遍历 找到这个数字就返回 找不到就提示用户下 这个数字不存在 int SLFind(SL* ps,SLDateType x) {assert(ps);int…

27_Scala功能函数

文章目录 功能函数1.功能函数处理集合数据2.扁平化操作3.按照指定条件将数据集中的数据进行过滤4.集合通过 自定义函数进行分组5.mapValues6.sortBy函数 功能函数 1.功能函数处理集合数据 –集合的功能函数 map List --> map( logical ) --> newList–实现一个不确定的…

【Arduino】Free RTOS系统

目录 1、任务创建 2、任务删除 3、延迟函数 4、示例&#xff1a; ESP32的SDK包中内置了FreeRTOS&#xff0c;在FreeRTOS中&#xff0c;线程&#xff08;Thread&#xff09;和任务&#xff08;Task&#xff09;的概念是相同的。每个任务就是一个线程&#xff0c;有着自己的一…

QT实现Home框架的两种方式

在触摸屏开发QT界面一般都是一个Home页面&#xff0c;然后button触发进入子页面显示&#xff0c;下面介绍这个home框架实现的两种方式&#xff1a; 1.方式一&#xff1a;用stackedWidget实现 &#xff08;1&#xff09;StackedWidget控件在Qt框架中是一个用于管理多个子窗口或…

【多模态】30、GPT4V_OCR | GPT4V 在 OCR 数据集上效果测评

文章目录 一、背景二、测评2.1 场景文本识别2.2 手写文本识别2.3 手写数学公式识别2.4 图表结构识别&#xff08;不考虑单元格中的文本内容&#xff09;2.5 从内容丰富的文档中抽取信息 三、讨论 论文&#xff1a;EXPLORING OCR CAPABILITIES OF GPT-4V(ISION) : A QUANTITATIV…

为什么Python中会有集合set类型?

知乎上有人提问&#xff0c;为什么Python有了列表list、元组tuple、字典dict这样的容器后&#xff0c;还要弄个集合set&#xff1f; 确实set和list、tuple、dict一样&#xff0c;都是python的主要数据类型&#xff0c;它们的作用是不同的。 因为set是数学意义上的集合&#xf…

Kubernetes进阶对象Deployment、DaemonSet、Service

Deployment Pod 在 YAML 里使用“containers”就可以任意编排容器&#xff0c;而且还有一个“restartPolicy”字段&#xff0c;默认值就是 Always&#xff0c;可以监控 Pod 里容器的状态&#xff0c;一旦发生异常&#xff0c;就会自动重启容器。 不过&#xff0c;“restartPo…