系统编程--Linux下文件的“其他操作”函数

这里写目录标题

  • 文件存储理论补充
    • dentry、inode
  • 文件其他操作
    • stat函数
      • 作用
      • 函数原型
      • 代码(以获取文件大小为例)
      • 补充(获取文件类型)
    • lstat函数
      • 作用
      • 函数原型
      • 代码
      • 补充(获取文件权限)
      • 总结
    • tips
    • link函数
      • 作用
      • 简介
      • 函数原型
      • 代码(模拟mv命令进行文件重命名)
    • unlink
      • 作用
      • 简介
      • 代码
    • 补充:隐式回收
      • 问题产生
      • 解决问题
    • readlink
    • rename

文件存储理论补充

dentry、inode

在这里插入图片描述

首先我们知道,inode,在创建硬链接的时候用到过,如下图:
在这里插入图片描述
当我们创建一个文件的硬链接时,该硬链接会有一个与文件一样的Inode

但是Indoe是什么:
Inode是一个结构体,存储着文件属性的结构体,他会存储一个文件的各种属性,以及“该文件在磁盘中的位置”,但是没有存储文件名

而dentry,存储着文件名+该文件的inode,相当于是一个目录,其名字也是"目录项"

当我们描述一个文件时,首先会根据dentry,找到他的inode,之后就知道了该文件的各种属性,而通过inode记录的文件的磁盘位置,就可以看到文件的内容了

而我们平时创建硬链接的底层原理是:
在这里插入图片描述
创建一个硬链接,就会创建出一个dentry,其文件名就是硬链接的文件名,匹配的就是目标文件的inode,这样就建立了硬链接,这也是为什么硬链接会与原文件有相同的inode

而删除硬链接,以及删除文件:
在这里插入图片描述
删除硬链接,其实就是删除dentry,删除一个dentry,其硬链接计数就会减一

当删除完所有的硬链接,然后又删除了文件,那么就会把所有的dentry都删除了,那么这个文件的inode就没有dentry引用了

但是此时,在磁盘中的文件安然无恙,也就是说,删除文件并不会真正的去磁盘中删除文件,而这个磁盘的内容,只有在没有dentry引用其inode的情况下,会被其他文件所覆盖,覆盖了才是真正意义的删除

数据恢复:
在这里插入图片描述
如果磁盘文件内容还没有被覆盖,我们就可以对该部分数据再次建立一个inode以及dentry,就可以做到对数据的恢复

文件其他操作

stat函数

man 2卷

作用

获取文件的各种属性

函数原型

在这里插入图片描述
参数一:文件路径(精确到文件名)
参数二:传出参数,指向struct stat类型的变量的指针

其中 stat结构体的内容:(实际上就是inode的内容,也就是我们平时ls -l (小L)显示的内容)
在这里插入图片描述

在这里插入图片描述

代码(以获取文件大小为例)

在这里插入图片描述
最终在sbuf结构体中已经有了该文件的所有属性,想打印哪个就打印哪个

这里我们打印文件的大小,这个可以实现与“lseek获取文件大小”相同的效果,且该方式是推荐的方法

注意使用%ld进行打印,其类型为unsinged long int

补充(获取文件类型)

在这里插入图片描述
拿到stat结构体变量中的数据后,在该结构体中有一个st_mode属性,利用该属性,配合其提供的宏函数,我们可以完成上图中的一些判断(如判断该文件是否是一个普通文件、还是一个目录?…)

而宏函数一般只返回0或1,也就是返回真或者假,他会告诉你是或不是

代码:
在这里插入图片描述

但是:
当我们测试其他类型没有问题,但当我们测试“符号链接”类型时,出现了问题:

首先我们创建两个符号链接:
在这里插入图片描述
在这里插入图片描述

结果是:在这里插入图片描述

可以看到,最终打印的都是符号链接所指向的最终的实体文件,该现象称为stat穿透,默认情况下stat是穿透的,如何解决,看下一个函数

lstat函数

作用

解决stat函数的“穿透”现象

函数原型

与stat函数原型一样

代码

在这里插入图片描述
与stat函数使用规则一样,只不过加了一个 “l” (小L)

结果:
在这里插入图片描述

在这里插入图片描述
实际上,我们的vim、cat,都是穿透的(作用到最终指向的实体文件)
而ls -l 是不穿透的 (作用于“链接本身”)

补充(获取文件权限)

在这里插入图片描述
在man中的demo没有使用宏函数进行文件类型的判断,而是使用了位运算

简单解释一下:
这里还是用到了位图:
在这里插入图片描述
一个位图,有2字节,16位,从右向左,每三个为一组,一共三组,共9位,分别代表不同组的文件权限(用户、用户组、其他用户)
再往左三位是特殊权限位
最开始的四位是文件类型,四位,转为八进制其总数就是17(即017,0是八进制的前缀)

上图中的S_IFMI就是017,也就是其二进制为1111 000 000 000 000,由于他前面都是1,所以可以作为掩码使用,所以st_mode & S_IFMT,最终得到S_IFMT下面的宏,就对应其表示的信息,由此可见,使用该方式,不仅可以获取到文件类型(宏函数可以获取),还可以获取到不同组的执行权限等信息(宏函数获取不到):
在这里插入图片描述

总结

在这里插入图片描述
因为lstat与stat没有其他区别,而且lstat不会进行穿透,所以,以后我们直接使用lstat就可以了

tips

在这里插入图片描述
在一些重要的函数的man手册中,我们点击“G”,会跳到最下面,这里可能会有一个当前函数的demo示例

link函数

man 2卷

作用

在这里插入图片描述
我们之前创建硬链接,都是通过命令行的ln命令,但是在代码中,我们不可能去到终端敲命令,所以就有了link函数,他就是负责创建硬链接的,实际上,是为文件新建一个dentry项

通过上面这张图我们也能知道,硬链接不像软链接,他在ll时,并不会表现为链接文件名,而是类似于创建了一个新文件,这也符合硬链接的原理:创建多个dentry,指向inode,所以,一个文件被刚创建时,系统就自动的为其创建了一个dentry,这就是我们常见的文件

简介

在这里插入图片描述
建立硬链接,也就是新建dentry项,而使用mv命令修改文件名时,也是修改了dentry,并不对真正的文件做操作(利用原先的dentry,创建出一个新的dentry,之后将原先的系统创建的dentry删除,就完成了文件的改名)

函数原型

在这里插入图片描述
参数一:原先的文件的dentry路径(精确到文件名)
当我们创建一个新的文件时,系统在磁盘写入了文件之后,会自动创建一个dentry,这个就是我们平时看到的文件

参数二:新的dentry路径(若没有,系统自动创建,一般是没有,因为硬链接都是新建的)

代码(模拟mv命令进行文件重命名)

在这里插入图片描述

效果:
在这里插入图片描述
先利用原先系统创建的dentry,建立新的dentry,之后将原先的那个删掉,使用unlink函数,直接传入文件路径即可

unlink

作用

解除一个硬链接(或者当前文件只有一个dentry时(也就是硬链接计数为1,即文件刚创建的状态),对当前文件进行“删除”(只是让其具备删除条件))

简介

在这里插入图片描述
可以看到,这里也说了,当一个文件的目录项(dentry)没有时,该文件会被操作系统择机释放,因此,我们删除一个文件,只是让文件具备了被释放的条件,什么时候释放,由系统决定,且打开该文件的进程必须关闭了,才能被释放

代码

需求:我们要在一个程序运行时,创建并打开一个文件,在程序结束时,这个文件要被销毁

在这里插入图片描述
在这里插入图片描述
我们在程序的末尾,在return之前,将该文件unlink掉,就可以实现上述的需求了

在程序第35行,设置了一个getchar(),该函数的作用是与用户进行IO交互,这里相当于“阻塞”,阻塞程序,不让程序结束,这样可以方便我们进行测试,(例如在另一个终端查看程序未结束时,那个临时文件在不在)

但是,假如说我们的程序在执行到39行之前,程序崩了,那么无法执行后续的代码便使得主函数退出了,这样的话,那个临时文件就不会被删除,如下图:
在这里插入图片描述
假如说,我们在34行,对p这个只读变量进行写入操作,那么会发生段错误(访问非法内存,或更改只读变量),程序崩溃,由此一来,那个临时文件不会被删除

如何解决:
在这里插入图片描述
直接将该部分unlink代码,放到open后面

我们不用担心在这里把临时文件unlink掉之后,后续的代码就找不到文件了,这个是不会的,因为unlink,只是将dentry删除,文件还在磁盘,等待所有使用该文件的进程结束了,系统才会择机释放,当前进程使用着临时文件,所以该文件不会被释放,仍然存在,这样,就不怕后续发生程序崩溃导致unlink没执行了

而如果程序正常进行,此时就算有阻塞,我们开另一个终端去查该临时文件,也是找不到的,而向该文件写入的内容,是被写入到了内核缓冲区里面

补充:隐式回收

问题产生

在这里插入图片描述
我们程序发生了段错误,程序崩溃,后续的close没有执行,那这个fd会一直占用着系统资源吗(占位符3,0、1、2是标准输入输出出错)

解决问题

在这里插入图片描述
答案是不会,因为程序的进程一旦被退出,那么该进程所有的内存资源都会被回收,这一过程称为“隐式回收”,也就是一个进程被关闭时,所有的内存会被释放(包括泄露的和不泄露的),但是也不能忽视内存泄漏,因为很多程序是一直处于开启状态进行监听的,程序一直运行,无法关闭,就无法隐式回收

readlink

在这里插入图片描述
在我们创建一个软链接后,其软链接的大小是指:创建连接时,敲入的链接文件的路径,被他当做字符串存了起来

而我们如何查看一个已有的软链接的指向呢,使用cat是不行的,因为他会进行穿透

所以使用一个命令:readlink,就可以拿到软链接链接的文件路径(创建时使用的相对路径会显示相对路径,创建时使用的绝对路径,就会显示绝对路径)
在这里插入图片描述
该命令也有一个函数,将结果返回到缓冲区buf中

rename

在这里插入图片描述

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

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

相关文章

有哪些好用的 AI 学术研究工具和科研工具?

AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频百万播放量https://aitools.jurilu.com/ AI 应用其实分两个层面,第一是模型,第二是应用。现在很多模型厂家都是既做 toC 的对话应用,也做 t…

使用API有效率地管理Dynadot域名,处理域名推送请求

简介 Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮箱&…

Nginx学习-相关概念

Nginx学习-相关概念 主要学习几个概念:Nginx,正向代理、反向代理、负载均衡、动静分离。–2020年05月29日 什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。 特点是占有内存少&…

绘制混淆矩阵热力图

Python绘制混淆矩阵热力图 用matplotlib绘制混淆矩阵,可以通过改变 imshow 函数中的 cmap 参数来修改颜色。cmap 参数接受一个 colormap 的名字,你可以选择许多不同的 colormap,例如 ‘viridis’, ‘plasma’, ‘inferno’, ‘magma’, ‘civ…

Rust代码答疑报错|Python一对一辅导答疑

Question 你好,我是悦创。 学员答疑: https://code.bornforthis.cn/?id4e72084d-1eaf-44ed-8067-744671491574https://code.bornforthis.cn/?id664ff169-41d6-409f-a05b-02ed42279759 问题代码: // You can bring module paths into sc…

阶梯-度小满春招算法方向第1批

问题的题面是典型的最长上升子序列问题。求方案数属动态规划问题&#xff0c;可推出以a[i]为最大节点的上升子序列方案数公式 dp[i]{dp[j] , 1<j<i-1&&f[j]1f[i]} &#xff08;f为最大上升子序列&#xff09;。 并且这个方案总数不会超过n&#xff0c;因此也…

C++相关概念和易错语法(24)(map、迭代器分类)

1.map 在上篇文章中&#xff0c;我着重介绍了set&#xff0c;由于map和set同源&#xff0c;所以这次我会着重介绍map别于set的地方 &#xff08;1&#xff09;模板参数 set是以单一的key作为成员变量&#xff0c;而map是以pair作为成员变量&#xff0c;而pair的first作为key来…

mysql对数据库的增删改

目录 DML语句&#xff1a; 增加数据&#xff08;insert语句&#xff09; 增加数据&#xff08;insert into select&#xff09; 修改数据&#xff08;update语句&#xff09; 【where 子句条件】 删除数据&#xff08;delete语句&#xff09; 删除数据&#xff08;trunca…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十一章 物理地址与虚拟地址

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

C# 委托函数 delegate

在C#中&#xff0c;委托&#xff08;Delegate&#xff09;是一种特殊的类型&#xff0c;它可以持有对方法的引用。 委托是实现事件的基础。事件本质上是多播委托&#xff0c;允许多个方法被触发 委托允许你将方法作为参数传递给其他方法&#xff0c;或者将方法作为返回值从方法…

基于生物地理算法的MLP多层感知机优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 生物地理算法&#xff08;BBO&#xff09;原理 4.2 多层感知机&#xff08;MLP&#xff09; 4.3 BBO优化MLP参数 5.完整程序 1.程序功能描述 基于生物地理算法的MLP多层感知机优化mat…

昇思25天学习打卡营第23天|ShuffleNet图像分类

ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&#xff1a;Pointw…

Validated 中常用的注解

Validated 中常用的注解 导入依赖常用注解嵌套校验校验注解的三个参数在post 和 [get](https://so.csdn.net/so/search?qget&spm1001.2101.3001.7020) 请求上使用 添加全局异常处理器&#xff0c;处理参数验证异常 导入依赖 <dependency><groupId>org.spring…

蒙特卡罗模型★★★★★

该博客为个人学习清风建模的学习笔记&#xff0c;部分课程可以在B站&#xff1a;【强烈推荐】清风&#xff1a;数学建模算法、编程和写作培训的视频课程以及Matlab等软件教学_哔哩哔哩_bilibili 目录 1引例&#xff1a;布丰投针实验 2蒙特卡罗方法概述 2.1定义 2.2提出 2…

基于词级ngram的词袋模型对twitter数据进行情感分析

按照阿光的项目做出了学习笔记&#xff0c;pytorch深度学习实战项目100例 基于词级ngram的词袋模型对twitter数据进行情感分析 什么是 N 符&#xff1f; N 格是指给定文本或语音样本中 n 个项目的连续序列。这些项目可以是音素、音节、字母、单词或碱基对&#xff0c;具体取…

C++ 基础和基本语法

文章目录 1. 简介 2. 基本解释 示例解释 3. 程序结构 HELLO WORLD 编译 & 执行 C 程序 4. 分号 和 语句块 5. 标识符 6. 关键字 7. 注释 1. 简介 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xff0c;支持过程化编程、面向对象编…

JAVA毕业设计634—基于Java+SSM的校园快递物流管理系统(源代码+数据库+11000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSSM的校园快递物流管理系统(源代码数据库11000字论文)634 一、系统介绍 本项目分为用户、快递员、管理员三种角色 1、用户&#xff1a; 注册、登录、待取件信息管理、快…

【视觉SLAM】 十四讲ch5习题

1.*寻找一个相机&#xff08;你手机或笔记本的摄像头即可&#xff09;&#xff0c;标定它的内参。你可能会用到标定板&#xff0c;或者自己打印一张标定用的棋盘格。 参考我之前写过的这篇博客&#xff1a;【OpenCV】 相机标定 calibrateCamera Code来源是《学习OpenCV3》18.…

全国区块链职业技能大赛国赛考题前端功能开发

任务3-1:区块链应用前端功能开发 1.请基于前端系统的开发模板,在登录组件login.js、组件管理文件components.js中添加对应的逻辑代码,实现对前端的角色选择功能,并测试功能完整性,示例页面如下: 具体要求如下: (1)有明确的提示,提示用户选择角色; (2)用户可看…

2024年第二季度 DDoS 威胁趋势报告

2024 年上半年&#xff0c;Cloudflare 缓解了 850 万次 DDoS 攻击&#xff1a;第一季度 450 万次&#xff0c;第二季度 400 万次。总体而言&#xff0c;第二季度 DDoS 攻击数量环比下降了 11%&#xff0c;但同比增长了 20%。 DDoS 攻击分布&#xff08;按类型和手段&#xff09…