Linux——文件标识符

目录

一、文件基础

二、常见的C语言文件接口

三、系统文件接口 

四、理解语言与系统文件操作的关系

五、如何理解一切皆文件

六、文件标识符再理解


一、文件基础

一个空文件,也会占用磁盘空间,这是因为文件不仅仅有存放在里面的内容,还有属性,比如文件名。创建时间,文件权限等。

文件 = 内容 + 属性。我们对文件的操作,无非是对内容或者对属性的操作。我们知道,=文件是存储在磁盘中的,如果我们打开文件,需要将文件加载到内存中,这样CPU才可以对文件进行处理。打开文件的本质,就是将文件加载到内存

操作系统在运行过程中,可能会打开很多文件,因此操作系统要对打开的文件进行管理。管理的本质操作就是先描述在组织。因此在内核中一定存在已打开文件的结构体,他们依次用链表存储起来,操作系统对文件的管理转为对链表的增删查改。

今天我们着重学系的就是进程与被打开文件的关系。

二、常见的C语言文件接口

  • fopen() —— 打开文件;
    • FILE * fopen ( const char * filename, const char * mode );
  • fclose() —— 关闭文件;
    • int fclose ( FILE * stream );

C语言写入函数

C语言读取函数 

使用fputs写入函数测试下。 

其中“w”权限是写入,没有文件就先创建文件,在写入前会先清空文件内容。在linux中还有一个方法可以进行w写入,就是输出重定向。> 

还有“a”,追加方式,他不会在写入前清空文件内容,而是在文件内容末尾继续追加新内容。linux中的追加重定向为  >> 

重定向这里先了解一下,后续会继续讲解。

三、系统文件接口 

我们知道,打开文件是要将文件加载到内存中,我们之前的操作是使用进程打开文件,进程是没有这么大的权利的,他肯定是调用了操作系统给我们的系统接口。虽然刚刚我们没有调用系统接口,用的是C语言给我们的接口,但其实,C语言打开文件的接口,底层是封装了系统调用接口的!!

系统接口open,第一个参数为路径+文件名,第二个参数是以什么样的方式打开,第三个参数对已创建的文件可以不填,对未创建的文件表示对文件设置什么权限。创建成功返回值为文件描述符file descriptor(简称fd),创建失败返回值为-1。

主要方式如下

  • O_RDONLY:只读模式
  • O_WRONLY:只写模式
  • O_RDWR:可读可写
  • O_APPEND 表示追加,如果原来文件里面有内容,则这次写入会写在文件的最末尾。
  • O_CREAT 表示如果指定文件不存在,则创建这个文件
  • O_EXCL 表示如果要创建的文件已存在,则出错,同时返回 -1,并且修改 errno 的值。
  • O_TRUNC 表示截断,如果文件存在,并且以只写、读写方式打开,则将其长度截断为0。

这些方式是通过位图来实现的,比如O_RDONLY为00000001,O_WRONLY为00000010,O_RDWR为00000100,如此类推,需要使用指定的方式,我们直接进行或运算就好。

运行结果如下,我们创建了log.txt文件,但权限为664,而不是我们代码中的0666,这是因为我们系统权限掩码为0002的原因,0666 &(~0002)= 0664。

写数据的系统接口为write,第一个参数代表往那个文件中写入(是open打开文件获取的文件描述符fd),第二个参数需要写入的字符串,第三个参数为写入的字节数。返回值为实际写入了多少字节的数据。

写入代码

成功写入

我们使用的为O_WRONLY | O_CREAT,只写的方式,没有文件就创建。因此如果再进行写入,并不会将文件内容清空,而是进行覆盖。

如下将str进行修改,再执行命令,查看log.txt的内容,发现good覆盖上了hell 。

 如果我们打开方式  | O_TRUNC,就会在打开前先清空文件。

 如果我们打开方式  | O_APPEND,会从文件结尾处开始写入,这是追加(不清空文件)。

四、理解语言与系统文件操作的关系

经过前面的学习,我们知道C语言文件的处理底层是封装了系统调用接口的,但是C语言fopen返回的是FILE* 指针,而系统open返回的是int类型整数fd,后续也是通过fd来对指定文件做处理的。

那么fd存放的内容是什么呢?我们通过如下代码打印出来看。

发现fd从 3 开始,是连续的小整数。 为什么不从0开始呢,0 1 2这三个去哪里了。如下

进程在运行的时候,默认是把这三小只打开的。但是这三小只不是硬件嘛,怎么跟文件扯上关系了,因为Linux下,一切皆文件。(后面会讲)

我们是通过进程对文件进行处理,那么进程的task_struct里面存在一个files_struct指针指向文件描述符表,里面有很多数据,其中有一个struct file* fd_array[]的数组指针,他指向被打开的文件结构体,这个索引就是文件描述符。如下图所示

但我们查看C标准库,发现这三个变量类型为FILE* 。  

File是C语言提供的结构体类型,fopen的底层是open,那么File结构体里面必定封装了文件描述符。我们通过如下代码也能印证一番

操作系统默认将stdin  stdout  stderr 打开,就是为了让程序员方便进行输入输出代码。就可以直接scanf 和 printf进行输入和显示。我们C语言第一个头文件基本都是stdio.h,stdio就是标准输入输出,C++第一个头文件 iostream,输入输出流。

五、如何理解一切皆文件

操作系统要管理硬件,也是先描述在组织,会将各种硬件使用结构体组织起来,不同的硬件,读写的方法肯定是不一样的,但是struct file里的接口read和write函数指针会指向对应硬件的读写。这样从统一的视角去看待不同硬件。我们也就理解了为何文件先会打开0  1  2这三小只。

六、文件标识符再理解

我们知道了0  1  2号文件标识符分别为stdin,stdout,stderr,也知道了linux一切皆文件,那么我们尝试下使用  read与write + 文件标识符  进行读写来代替(scanf和printf)。

read函数第一个参数fd为文件标识符,第二个参数为读取的数据保存到buf缓冲区中,第三个参数为读取的字节数,返回值为带符号整数(实际读取字节数,失败返回-1)

write函数第一个参数fd也为文件标识符,第二个参数为从buf缓冲区中写入数据到文件,第三个参数为写入的字节数,返回值为带符号整数(实际写入字节数,失败返回-1)

代码如下,从0(stdin)中读取输入到buffer,从buffer写入数据到1(stdout)中。 

成功输出我王慕霸没有开挂!!!! 

我们知道,打开文件fd是从3开始,按顺序依次累加。如果我们先关闭某一个或几个fd文件,那么新打开的文件还是从3开始吗?

使用下面代码测试下

发现是从索引0开始,往后依次查找空位进行放入,比如fd1找到0不存在,就放入到0位置,fd2发现0  1   2都存在,3不存在,就放入3位置。

 如果你关掉了1,虽然fd也会放入1位置,但是不会打印,因为1号为标准输出,关闭还打印个啥

 

 

 

 

 

 

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

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

相关文章

赋能汽车电动化与智能化,AUTO TECH 2024 华南展专业观众预登记开始啦!

赋能汽车电动化与智能化,AUTO TECH 2024 华南展专业观众预登记开始啦! 一年一度的 AUTO TECH 又将来临, 2024年5月15-17日与您相约广州保利世贸博览馆, 本次展会汇聚全球传统车企、新势力车企等最新的造车技术,零部件…

纯css实现太极八卦图

感觉最近好像闯鬼了&#xff0c;赶紧写个八卦图避避邪&#xff0c;开玩笑了&#xff0c;不废话&#xff0c;上菜&#xff0c;看效果上代码。 效果 代码&#xff0c;你们都是大佬&#xff0c;这里就不解释代码了 &#xff08;hover会转动喔&#xff09;。 <!DOCTYPE html&g…

知名比特币质押协议项目Babylon确认参加Hack.Summit()2024区块链开发者大会

Babylon项目已确认将派遣其项目代表出席2024年在香港数码港举办的Hack.Summit()2024区块链开发者大会。作为比特币生态的领军项目&#xff0c;Babylon积极参与全球区块链领域的交流与合作&#xff0c;此次出席大会将为其提供一个展示项目进展、交流技术与创新思路的重要平台。B…

信奥一本通:2025:【例4.11】体操队

其实这个数有规律&#xff0c;这个数取余23456的结果都是1&#xff0c;因为每排两人&#xff0c;多一个&#xff0c;就相当于除2余1.每排三人&#xff0c;多一人&#xff0c;除3余1。那么根据这个就能确定结果了 #include <iostream> using namespace std; int main(){i…

YOLOv8改进 | 主干篇 | 轻量级的低照度图像增强网络IAT改进YOLOv8暗光检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是轻量级的变换器模型:Illumination Adaptive Transformer (IAT),用于图像增强和曝光校正。其基本原理是通过分解图像信号处理器(ISP)管道到局部和全局图像组件,从而恢复在低光或过/欠曝光条件下的正常光照sRGB图像。具体来说,IAT…

最小二乘法(带你 原理 实践)

文章目录 引言一、最小二乘法的基本原理二、最小二乘法的计算过程建立模型确定目标函数求解模型参数模型检验 三、最小二乘法的优缺点优点原理简单易懂统计特性优良适用范围广泛 缺点对异常值敏感假设条件较多 四、最小二乘法在实际应用中的案例五、如何克服最小二乘法的局限性…

代码之旅:我的算法探索之路(二)力扣 最接近的三数之和

目录 LeetCode 第16题 最接近的三数之和 题目 解题思路 代码 结果 LeetCode 第18题 四数之和 题目 解题思路 代码 结果 LeetCode 第16题 最接近的三数之和 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使…

【Azure 架构师学习笔记】- Azure Private Endpoint

本文属于【Azure 架构师学习笔记】系列。 前言 公有云的其中一个特点是默认允许公网访问&#xff0c; 这就对企业环境带来风险&#xff0c;也是很多年前企业对公有云抵触的其中一个原因&#xff0c;现在这类问题已经很少&#xff0c;因为有了很多技术来确保云上的资源被安全地…

技术小知识:云计算服务下的IaaS,PaaS,SaaS⑥

一、云计算 云计算起源仿照天空的云朵聚集&#xff0c;对大量服务器的远程管理。以便能对服务器做空间、资源的最大利用和降低操作执行命令的复杂度。 二、云计算衍生下的服务 在服务器以一种云的形式存在&#xff0c;衍生除了很多服务提供&#xff0c;以便用户可以方便&#x…

一种灵活的数据权限思路(AOP、反射、MyBatis拦截器)

来源:juejin.cn/post/7267090979537944631 来源:juejin.cn/post/7308992638468227109 1 前言 2 需求 3 设计思路 4 例子1 查看订单金额大于100且小于500的订单 规则配置 代码 5 例子2 查看收货人地址模糊查询钦南区的订单 规则配置 代码 6 当然,一键代码生成,一句代码都不…

C#,动态规划的集合划分问题(DP Partition problem)算法与源代码

1 动态规划问题中的划分问题 动态规划问题中的划分问题是确定一个给定的集是否可以划分为两个子集&#xff0c;使得两个子集中的元素之和相同。 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程…

基于UDP实现直播间聊天的功能

需求&#xff1a;软件划分为用户客户端和主播服务端两个软件client.c和server.c 用户客户端负责&#xff1a;1.接收用户的昵称2.接收用户输入的信息&#xff0c;能够将信息发送给服务端3.接收服务端回复的数据信息,并完成显示主播服务端负责&#xff1a;1.对所有加入直播间的用…

无尘车间:保障电子产品品质与员工健康

在当今数字化时代&#xff0c;电子产品已经成为我们生活中不可或缺的一部分。从智能手机到计算机&#xff0c;从家用电器到汽车电子系统&#xff0c;电子产品无处不在&#xff0c;给我们的生活带来了便利与快捷。然而&#xff0c;这些高科技产品的背后是一系列复杂的制造过程&a…

Paddle上手实战——NLP经典cls任务“推特文本情感13分类”

Paddle上手实战——NLP经典cls任务“推特文本情感13分类” 实战背景介绍 数据地址:https://www.heywhale.com/home/activity/detail/611cbe90ba12a0001753d1e9/content Twitter推文具备多重特性,首要之处在于其与Facebook的显著区别——其完全基于文本形式,通过Twitter接…

基于docker安装的Jenkins实现python执行自动化测试程序

背景 通过Jenkins实现自动化测试,在全局配置中配置好后,执行构建发生如下错误 解决办法: 在Jenkins中插件管理中下载python后,回到Jenkins容器中 查找刚下载的python所在位置 到Jenkins中全局配置中修改脚本 1.可以在环境变量中定义python所在位置 2.在一下图示中进行获取…

Rust泛型与trait特性,模仿接口的实现

泛型是一个编程语言不可或缺的机制。 C 语言中用"模板"来实现泛型&#xff0c;而 C 语言中没有泛型的机制&#xff0c;这也导致 C 语言难以构建类型复杂的工程。 泛型机制是编程语言用于表达类型抽象的机制&#xff0c;一般用于功能确定、数据类型待定的类&#xf…

VMware Workstation安装Linux虚拟机与虚拟机克隆,特别适合搭建虚拟机集群环境,工作效率直线上升~

虚拟机 一、安装虚拟机二、克隆虚拟机三、配置静态IP地址一、安装虚拟机 设置虚拟机名称与安装位置 设置磁盘大小 配置硬件参数

Redis主从架构和管道Lua(一)

Redis主从架构 架构 Redis主从工作原理 如果为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。master受到PSYNC命令&#xff0c;会在后台进行数据持久化通过bgsave生成最新的 RDB快照文件&#xff0c;持久化期间…

Linux阻塞与非阻塞IO简介

一. 简介 阻塞与非阻塞IO是Linux驱动开发中很常见的两种设备访问模式&#xff0c;在编写驱动的时候&#xff0c;一定要考虑到阻塞和非阻塞。 本文来学习一下&#xff0c;什么是 Linux下的阻塞与非阻塞IO访问。 二. Linux阻塞与非阻塞IO 这里的 “IO” 并不是我们学习 STM32…

[机器视觉]halcon十二 条码识别、字符识别之字符识别

[机器视觉]halcon十二 条码识别、字符识别之字符识别 流程 获取图像-》创建模型-》查找文本-》清除模型 效果 算子 create_text_model_reader &#xff1a; 创建文本模型 find_text : 查找文本 get_text_result &#xff1a;获取文本内容 set_text_model_param : 设置文本模板…