【基础IO⑧】:文件描述符fd(进程与文件的联系)
【基础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.所以我们可以观察他们的文件描述符是什么。
相关文章:

【基础IO⑧】:文件描述符fd(进程与文件的联系)
【基础IO⑧】:进程与文件之间的联系(文件描述符fd) 一.前言探讨[进程与文件关系]二.C语言文件操作三.系统文件调用1.open/write 四.文件描述符fd 一.前言探讨[进程与文件关系] 我们首先了解一些基本的认识: 1.文件包括文件内容和文件属性 2.…...

搭建WAMP网站教程(windows+apache+mysql+php)
之前为了学习网络安全,从搭建网站学起,对网站运行有个初步的了解。 今天翻到了之前的笔记,顺手发到csdn上了。 搭建网站步骤 一、Apache 安装Apache,下载Apache之后把Apache解压,此处解压到C:\目录下 2.然后要记得安…...

瓦斯抽采VR应急救援模拟仿真系统筑牢企业安全生产防线
矿工素质对安全生产的影响很大。传统的煤矿安全事故培训出于条件差、经验少加上侥幸心理,导致其在教学内容时过于简单且不切合实际,无法真正发挥培训作用。瓦斯检查作业VR模拟实操培训通过真实还原煤矿作业环境,让受训者身临其境地进入三维仿…...

nodelist 与 HTMLCollection 的区别
原地址 https://cloud.tencent.com/developer/article/2013289 节点与元素 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点每个 HTML 元素是元素节点HTML 元素内的文本是文本节点每个 HTML 属性是属性节点注释是注…...

系列十二、过滤器 vs 拦截器
一、过滤器 vs 拦截器 1.1、区别 (1)触发时机不一样,过滤器是在请求进入容器后Servlet之前进行预处理的,请求结束返回也是,是在Servlet处理完后,返回给前端之前; (2)过滤…...

dockerfile运行apk命令卡住的问题解决——更换镜像
在练习docker官方文档关于docker compose初体验(https://docs.docker.com/compose/gettingstarted/)过程中,执行dockerfile命令RUN apk add --no-cache gcc musl-dev linux-headers时,出现卡住的情况,等了几千秒都不行…...

Android - 编译 openssl 踩坑之路
一、简述 如果你想快速在项目中使用上 openssl,可以使用网上其他开发者提供好的预编译库: OpenSSL(All):https://builds.viaduck.org/prebuilts/openssl/OpenSSL(3.1.*) :https://github.com/217heidai/openssl_for_android以上的预编译库可能最低只支持 API 21(即 Andro…...

verdi技巧分享--合并多个fsdb文件、统计信号边沿
文章目录 0 前言1 如何显示信号高位的02 统计信号的上升沿、下降沿3 合并信号4 将多个fsdb文件合并成一个 0 前言 分享几个这段时间学到的verdi操作 1 如何显示信号高位的0 这个可能对一些有强迫症的有帮助吧 nand相关的操作,有一些特定的cmd,比如 r…...

czmq的4版本中CURVE怎么实现的两个程序之间使用的一个证书?
在CZMQ的4版本中,CURVE是一种加密机制,用于在两个程序之间建立安全的连接。要使用CURVE,你需要创建和分发公钥和私钥。以下是一个简单的步骤说明: 首先,你需要为每个程序生成一对公钥和私钥。你可以使用CZMQ的zcert类…...

Spring Boot整合Swagger
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…...

SpringBoot-WebSocket浏览器-服务器双向通信
文章目录 WebSocket 介绍入门案例 WebSocket 介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 应用场景: 视…...

Docker网络模式_Docker常用命令_以及Docker如何给运行的镜像内容连接互联网_Docker网络模式原理---Docker工作笔记004
然后我们来看一下docker的网络模式: 这个docker我们先看一下电脑上的网络,有两个,1个是lo是测试用的一个是enp0s3这个是我们以太网地址,然后我们去: 安装docker 安装后我们再去ip address可以看到多出来一个网络是docker0 这里ip地址是172.17.0.1这个是私有地址外部无法访问 这…...

爬虫项目-爬取股吧(东方财富)评论
1.最近帮别人爬取了东方财富股吧的帖子和评论,网址如下:http://mguba.eastmoney.com/mguba/list/zssh000300 2.爬取字段如下所示: 3.爬虫的大致思路如下:客户要求爬取评论数大于5的帖子,首先获取帖子链接,…...

【Midjourney入门教程2】Midjourney的基础操作和设置
文章目录 Midjourney的常用命令和基础设置1、 /imagine2、 /blend3、 /info4、 /subscribe5、 /settings(Midjourney的基础设置)6、 /shorten 有部分同学说我不想要英文界面的,不要慌: 点击左下角个人信息的设置按钮,找…...

后端使用DES加密,前端解密方法
前言: 现在为了防止用户直接篡改数据会采用加密的方式进行传输,加密的方法有很多种,这篇文章主要讲解下后端使用DES加密的数据传输给前端,前端接收到之后如何去解密。 操作步骤如下: 1.安装crypto-js npm install c…...

chrome 扩展 popup 弹窗的使用
popup的基本使用方法 popup介绍 popup 是点击 browser_action 或者 page_action图标时打开的一个小窗口网页,焦点离开网页就立即关闭,一般用来做一些临时性的交互。 popup配置 V3版本中(V2版本是在 browser_action 中 )&#x…...

Spring Security入门教程,springboot整合Spring Security
Spring Security是Spring官方推荐的认证、授权框架,功能相比Apache Shiro功能更丰富也更强大,但是使用起来更麻烦。 如果使用过Apache Shiro,学习Spring Security会比较简单一点,两种框架有很多相似的地方。 目录 一、准备工作 …...

如何在 Unbuntu 下安装配置 Apache Zookeeper
简介 Zookeeper 是 apache 基金组织下的项目,项目用于简单的监控和管理一组服务,通过简单的接口就可以集中协调一组服务,如配置管理,信息同步,命名,分布式协调。 准备工作 Ubuntu 23.04 或者 20.04访问…...

AI视觉领域流媒体知识入门介绍(二):深入理解GOP
GOP(group of pictures) 在流行的视频编码算法中,都包含GOP这个概念,例如MPEG-2, H.264, and H.265。 背景 关于视频存储和传输的“size”: Resolution 分辨率 Uncompressed Bitrate 未压缩时的比特率 1280720 (720p…...

C++ 代码实例:并查集简单创建工具
文章目录 前言代码仓库代码说明main.cppMakefile 结果总结参考资料作者的话 前言 C 代码实例:并查集简单创建工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) 代码 说明 简单地创建并查集注…...

Hadoop学习总结(Shell操作)
HDFS Shell 参数 命令参数功能描述-ls查看指定路径的目录结构-du统计目录下所有文件大小-mv移动文件-cp复制文件-rm删除文件 / 空白文件夹-put上传文件-cat查看内容文件-text将源文件输出文本格式-mkdir创建空白文件夹-help帮助 一、ls 命令 ls 命令用于查看指定路径的当前目录…...

LeetCode热题100——链表
链表 1. 相交链表2. 反转链表3. 回文链表4. 环形链表5. 合并两个有序链表 1. 相交链表 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 // 题解:使用A/B循环遍…...

使用C++的QT框架实现贪吃蛇
最近刷抖音经常看到别人使用类似chatGPT的al工具实现这个贪吃蛇游戏,正好我之前也写过,那么今天看看怎么去实现这个简单的游戏 我这边使用的是C的QT框架,当然用哪些框架都可以,主要是逻辑思路 1.生成画布,开始是一些…...

如何发布自己的golang库
如何发布自己的golang库 1、在 github/gitee 上创建一个 public 仓库,仓库名与 go 库名一致,然后将该仓库 clone 到本地。 本文这里使用 gitee。 $ git clone https://gitee.com/zsx242030/goutil.git2、进入项目文件夹,进行初始化。 $ go…...

梳理自动驾驶中的各类坐标系
目录 自动驾驶中的坐标系定义 关于坐标系的定义 几大常用坐标系 世界坐标系 自车坐标系 传感器坐标系 激光雷达坐标系 相机坐标系 如何理解坐标转换 机器人基础中的坐标转换概念 左乘右乘的概念 对左乘右乘的理解 再谈自动驾驶中的坐标转换 本节参考文献 自动驾驶…...

一个可以自动把微信聊天收到的二维码图片实时提取出来并分类的软件
10-1 如果你有需要实时地、自动地把微信各个群收到的二维码图片提取出来的需求,那本文章适合你,本文章的主要内容是教你如何实现自动提取微信收到的二维码图片,助你快速扫码,永远比别人领先一步。 首先需要准备好的材料…...

02-React组件与模块
组件与模块 前期准备 安装React官方浏览器调试工具,浏览器扩展搜索即可 比如红色的React就是本地开发模式 开启一个用React写的网站,比如美团 此时开发状态就变成了蓝色 组件也能解析出来 何为组件&模块 模块,简单来说就是JS代…...

项目实战:新增@RequestMapping和@GetMapping和@PostMapping三个注解
1、RequestMapping package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Inherited public interface RequestMapping {String value(); }2、PostMapping package com.csdn.mymvc.annotation; im…...

基于AOSP源码Android-10.0.0_r41分支编译,framework开发,修改系统默认字体大小
文章目录 基于AOSP源码Android-10.0.0_r41分支编译,framework开发,修改系统默认字体大小 基于AOSP源码Android-10.0.0_r41分支编译,framework开发,修改系统默认字体大小 主要修改一个地方就行 代码源码路径 frameworks/base/co…...

如何再kali中下载iwebsec靶场
这个靶场有三种搭建方法: 第一种是在线靶场:http://www.iwebsec.com:81/ 第二种是虚拟机版本的,直接下载到本地搭建 官网地址下载:http://www.iwebsec.com/ 而第三种就是利用docker搭建这个靶场,我这里是用kali进行…...