【基础IO⑧】:文件描述符fd(进程与文件的联系)

news2024/12/30 3:51:13

【基础IO⑧】:进程与文件之间的联系(文件描述符fd)

  • 一.前言探讨[进程与文件关系]
  • 二.C语言文件操作
  • 三.系统文件调用
    • 1.open/write
  • 四.文件描述符fd

一.前言探讨[进程与文件关系]

我们首先了解一些基本的认识:

1.文件包括文件内容和文件属性
2.文件分为打开文件和没有打开文件。
3.打开的文件是谁打开的呢?又是如何打开的呢?这是我们本篇的重点处理问题。
4.没有打开的文件在哪里放着呢?

对于打开的文件我们重点想了解是谁打开的,并且是如何打开的。对于没有打开的文件我们重点想了解这些没有被打开的文件在哪里!

1.打开的文件的操作肯定是我们写代码才能操作,所以也就是我们的程序即进程!是进程打开文件。
2.对于没有打开的文件肯定很多,那这些文件是如何被分门别类的放置好的呢?这是我们要探讨的问题,因为我们想对这些未打开的文件快速的进行增删查改。

进程打开了文件,本质上就是要研究进程和文件之间的关系。
要想访问一个文件,首先需要将文件加载到内存里,并且一个进程可以打开多个文件,所以操作系统内部肯定存在很多被打开的文件!那么这些被打开的文件操作系统也需要对他们进行管理。通过先描述再组织的方式进行管理---->每一个被打开的文件操作系统都会给它创建一个文件对象,这个对象包含文件的很多属性。

所以综上:我们要想探讨一个被打开的文件,本质上是探讨进程与文件之间的关系即------->进程PCB与文件对象之间的关系。

在这里插入图片描述

二.C语言文件操作

C语言的常见文件操作就是fopen fwrite,fread fclose等打开文件写入文件输出文件等操作。
对于fopen(参数1,参数2)的使用很简单,就是打开某个路径下的文件,以什么样的方式打开.
在这里插入图片描述
所以如果不指定文件在哪个路径下,系统会默认将当前进程的路径添加上去,也就是在当前进程目录下创建。
所以如果我们将进程的当前目录修改,就可以将文件新建到别的地方了。

1.‘w’就是以写的方式打开。不过要注意w在写入之前,都会对文件进行清空操作。比如像重定向里的,打开文件但不往里面写,就会直接清空文件,说明重定向操作里面打开文件的方式就是w。
2.‘a’也是写入操作,只不过在打开文件时不会清空文件,而是直接追加在内容末尾。
在这里插入图片描述
3.这里还有一个问题:就是当使用fwrite时,后面计算字符串的大小需不需要+1,因为\0的原因就很困扰,为什么有时加1有时不加1呢?
首先我们要明白,字符串是C语言规定出来的,它的后面必须要有\0。但文件就不认识C语言,文件只需字符的内容就可以了,所以当我们往文件里写入时字符串时,都不需要加+1,直接计算字符串的长度即可。在这里插入图片描述

还有一个知识:那就是C语言下,会默认给我们打开3个标准输入输出流:在这里插入图片描述

三.系统文件调用

文件其实是在磁盘上的,磁盘又是属于硬件设备。操作系统的构成,用户层在最上面,硬件在最下面,用户要想访问硬件必须要通过操作系统,而操作系统又因为安全性只会给你提供系统调用接口来访问。
所以所有的库函数,只要要访问硬件资源,就一定要封装系统调用接口。
在这里插入图片描述

1.open/write

在这里插入图片描述
有两个open接口,这两个的区别在于第三个参数有和没有。
对于已经存在的文件,肯定有它自己的权限设置,这样才可以被访问,所以当一个文件被创建时,必须要设置这个文件的权限属性。
而第三个参数就是用来设置权限的。所以第一个open是用来打开已经存在的文件,而第二个open是用来打开创建一个没有存在的文件的,并设置这个文件的权限。我们主要用三个参数的open调用接口。

open系统调用接口的参数第一个就是文件路径,第二个参数是打开的方式,第三个参数是用过给这个文件设计权限的。返回值是int类型
在这里插入图片描述

open是系统调用接口,它有自己的打开文件的方式,它是采用比特位方式的标志位传递参数从而采用不同的打开方式。

O_WRONLY表示只写形式
O_CREAT表示如果文件不存在就创建
O_TRYNC表示打开文件之前先清空文件
O_APPEND表示追加,不清空。

在这里插入图片描述
所以C库函数fopen里封装着open系统调用函数,"w"方式就是O_WRONLY, O_CREAT, O_TRYNC三种方式组合,"a"方式就是
O_WRONLY, O_CREAT, O_APPEND三种方式组合。

fopen封装着open这个我们应该能理解,不过你没有注意到open的返回值是int类型,而fopen的返回值确实FILE类型,int类型和FILE类型之间有什么关系呢?

四.文件描述符fd

我们知道只要打开一个文件,操作系统就要给这个打开的文件创建个文件对象struct file。这个对象描述着文件许多属性。文件对象之间用链表连起来。这样操作系统对于文件的管理,就转换为对链表的增删查改了。

我们前面也说过一个进程可以打开多个文件,所以操作系统内部肯定有许多被打开的文件,那么进程是怎么知道它打开的是哪个文件呢?

其实进程PCB里存在一个指针对象,叫做struct file_struct对象。
它指向的是一个结构体对象,这个结构体里面存着一个数组struct file
arr[],这个数组叫做文件描述符表,里面存的都是文件对象的地址。当进程要打开一个文件是,操作系统首先会为这个文件创建struct file对象。然后就会将这个对象地址存放在文件描述符表里。当又打开一个文件,就依次将文件对象的地址放进数组里面,最后返回该数组的下标给进程。最后调用open打开创建一个文件后,就会获得一个int类型的下标。所以本质上这个int类型的返回值就是数组的下标。也就是文件描述表的下标。而进程就是通过这个下标再次找到被打开的文件的。
在这里插入图片描述
所以这个下标也叫做文件描述符。本质上就是文件对象在文件描述表里位置。
所以进程是通过文件描述符fd来找到被打开的文件的。这也是为什么open返回值为什么是int类型了。
在这里插入图片描述

因为进程可以打开多个文件,所以这里采用的引用计数的方式进行关闭,每个文件对象都有一个计数器,当进程close这个文件时,计数器就减减,减完后如果计数器不为0,则说明还有其他进程在使用这个文件,则不真正关闭文件,当计数器为0时才真正的关闭文件。
在这里插入图片描述

open返回的是文件描述符fd。但fopen返回的确实FILE类型这是怎么回事呢?
其实在操作系统它只认识文件描述符fd,并不认识FILE
。进程与文件之间本质是通过数组下标来联系的。
所以不管FILE是什么,它内部肯定封装着文件描述符fd。FILE其实一个结构体对象。后面我会详细介绍它。

所以对于文件操作来说,进行了两次封装,一次是函数层面的封装:库函数封装系统调用,一次是类型方面封装:FILE类型里面封装fd类型。

到这里我们就可以验证一个现象了:
你说C语言默认给我们打开了三个标准输入输出流,你怎么证明呢?

文件既然被打开了,操作系统就会给它创建结构体对象struct file。并且会将它的地址放入文件描述符表里,一开始文件描述符表里一个都没有,现在这三个放进去,应该分别对应的数组下标是 0 1 2.所以我们可以观察他们的文件描述符是什么。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLO目标检测——真实道路车辆检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用:自动驾驶技术研发、交通安全监控数据集说明:真实道路车辆检测数据集,真实场景的高质量图片数据,数据场景丰富标签说明:使用lableimg标注软件标注,标注框质量高,含voc(xml)、coco(j…

STM32 IAP应用开发--bootloader升级程序

STM32 IAP应用开发--bootloader升级程序 Chapter1 STM32 IAP应用开发——通过串口/RS485实现固件升级(方式2)前言什么是IAP?什么是BootLoader? 方案介绍:1)bootloader部分:2)APP部分…

verilog 每日一练- 移位寄存器

module shift_1x64 (clk, shift,sr_in,sr_out,);input clk, shift;input sr_in;output sr_out;reg [63:0] sr;always(posedge clk)beginif (shift 1b1)beginsr[63:1] < sr[62:0];sr[0] < sr_in;endendassign sr_out sr[63];endmodule 这个Verilog模块 shift_1x64 实现了…

《算法通关村—迭代实现二叉树的前序遍历》

《算法通关村—迭代实现二叉树的前序遍历》 利用递归进行二叉树的前序遍历是非常容易的几行代码就能解决。但是你知道如何用迭代实现吗&#xff1f; 理论上来说能够用递归解决的都能用迭代解决&#xff0c;我们就来试试用迭代解决二叉树的前序遍历问题吧。 什么是前序遍历&a…

Photoshop 2023 v24.7

Photoshop是一款强大的图像编辑软件&#xff0c;被广泛应用于图像处理、图形设计、数字绘画等领域。它提供了丰富的图像编辑功能&#xff0c;可以用于调整图像的色彩、亮度、对比度等&#xff0c;添加特效、滤镜&#xff0c;以及进行复杂的图像合成和修复。 以下是Adobe Photo…

内存学习(2):内存分类与常用概念2(SDRAM与DDR)

SDRAM与DDR的简单概念介绍 SDRAM 定义&#xff1a; 同步动态随机存取内存&#xff08;Synchronous Dynamic Random-Access Memory&#xff0c;简称SDRAM&#xff09;是有一个同步接口的动态随机存取内存DRAM&#xff08;可以参考前文&#xff09;。可以理解为是一种利用同步…

Linux网络编程03

select的缺陷 &#xff08;1&#xff09;fd,set的本质是一个位图&#xff0c;容量是固定的1024&#xff0c;因此最大只能监听1024个连接 &#xff08;可以扩容&#xff09; &#xff08;2&#xff09;监听和就绪用的是同一个数据结构&#xff0c;使用困难 &#xff08;3&#x…

Nacos2.2.3版本运行startup.cmd出现闪退,无错误信息解决方法

Nacos2.2.3版本运行startup.cmd出现闪退&#xff0c;无错误信息解决方法 一、问题描述二、解决方法 一、问题描述 当我下载好nacos2.2.3版解压之后&#xff0c;直接双击startup.cmd出现闪退&#xff0c;而且 没有错误提示信息。后来经过一番搜索尝试&#xff0c;终于解决了自己…

InnoDB中Buffer Pool详解

1. 概念及特点 Buffer Pool 是 MySQL 中 InnoDB 存储引擎用来缓存表数据和索引数据的内存区域。这个内存区域被用来存储磁盘上的数据页的副本&#xff0c;这样常用的数据可以在内存中快速被访问&#xff0c;而不必每次都从磁盘中读取。 以下是 Buffer Pool 的一些重要特点&a…

kali Linux中更换为阿里镜像源

准备&#xff1a; kali Linux 阿里源链接 deb kali安装包下载_开源镜像站-阿里云 kali-rolling main non-free contrib deb-src kali安装包下载_开源镜像站-阿里云 kali-rolling main non-free contrib 配置&#xff1a; 打开kali 终端输入&#xff1a;sudo nano /etc/apt…

2023.11.5 关于 Spring 创建 和 使用

目录 创建 Spring 项目 1.创建 Maven 项目 2.添加 Spring 依赖 将 Bean 对象存储到 Spring 容器中 创建 Bean 存储 Bean ApplicationContext 获取 Bean BeanFactory 获取 Bean ApplicationContext 和 BeanFactory 的区别 获取 Bean 的三种方式 根据 Bean id 获取…

基于8086电压表系统仿真系统设计

**单片机设计介绍&#xff0c;1665基于8051单片机与1601LCD的计算器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 一个基于8086的电压表系统仿真系统可以分为硬件和软件两部分。 硬件部分包括输入设备&#xff08;例如模拟…

什么是缓冲区溢出?

缓冲区溢出 1. 什么是缓冲区溢出2. 缓冲区溢出攻击的类型3. 攻击者如何利用缓冲区溢出4. 如何防止缓冲区溢出攻击 1. 什么是缓冲区溢出 &#xff08;1&#xff09;缓冲区 缓冲区是一块连续的计算机内存区域&#xff0c;用于在将数据从一个位置移到另一位置时临时存储数据。这…

[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值

[动态规划] (七) 路径问题&#xff1a;LCR 166./剑指offer 47. 珠宝的最高价值 文章目录 [动态规划] (七) 路径问题&#xff1a;LCR 166./剑指offer 47. 珠宝的最高价值题目解析解题思路状态表示状态转移方程初始化和填表顺序 返回值代码实现总结 LCR 166. 珠宝的最高价值 题目…

一致性哈希在分库分表的应用

文章目录 前言分库分表方法一致性哈希介绍分库分表的应用 总结 前言 大家应该都知道一些哈希算法&#xff0c;比如MD5、SHA-1、SHA-256等&#xff0c;通常被用于唯一标识、安全加密、数据校验等场景。除此之外&#xff0c;还有一种应用是对某个数据进行哈希取模映射到一个有限…

【数据开发】大数据平台架构,Hive / THive介绍

1、大数据引擎 大数据引擎是用于处理大规模数据的软件系统&#xff0c; 常用的大数据引擎包括Hadoop、Spark、Hive、Pig、Flink、Storm等。 其中&#xff0c;Hive是一种基于Hadoop的数据仓库工具&#xff0c;可以将结构化的数据映射到Hadoop的分布式文件系统上&#xff0c;并提…

什么是防火墙?详解三种常见的防火墙及各自的优缺点

目录 防火墙的定义 防火墙的功能 防火墙的特性 防火墙的必要性 防火墙的优点 防火墙的局限性 防火墙的分类 分组过滤防火墙 优点&#xff1a; 缺点&#xff1a; 应用代理防火墙 优点 缺点 状态检测防火墙 优点 缺点 防火墙的定义 防火墙的本义原是指古代人们…

【蓝桥杯选拔赛真题11】C++求平方 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++求平方 一、题目要求 1、编程实现 2、输入输出 二、算法分析

基于.NET、Uni-App开发支持多平台的小程序商城系统 - CoreShop

前言 小程序商城系统是当前备受追捧的开发领域&#xff0c;它可以为用户提供一个更加便捷、流畅、直观的购物体验&#xff0c;无需下载和安装&#xff0c;随时随地轻松使用。今天给大家推荐一个基于.NET、Uni-App开发支持多平台的小程序商城系统&#xff08;该商城系统完整开源…

前端框架Vue学习 ——(二)Vue常用指令

文章目录 常用指令 常用指令 指令: HTML 标签上带有 “v-” 前缀的特殊属性&#xff0c;不同指令具有不同含义。例如: v-if, v-for… 常用指令&#xff1a; v-bind&#xff1a;为 HTML 标签绑定属性值&#xff0c;如设置 href&#xff0c;css 样式等 <a v-bind:href"…