初识Linux · 文件(1)

目录

前言:

回顾语言层面的文件

理解文件的预备知识

文件和磁盘

使用和认识系统调用函数


前言:

本文以及下篇文章,揭露的都是Linux中文件的奥秘,对于文件来说,初学Linux第一节课接触的就是文件,对于C语言,我们使用fopen可以打开文件,对于C++,我们可以使用ofstream可以打开文件,那么对于这么多打开文件的方式,难道每个不同的语言,我们都要单独去学习如何使用对应的函数吗?

当然不是,我们不妨回想最初学习的OS的结构图:

对于该结构,我们设想一个问题,文件属于哪里?

文件属于磁盘,而磁盘属于硬件,那么对于文件来说,我们能跨过OS直接操控文件吗?当然不可以,那么C语言提供的文件函数是否……?留个悬念。

现在就开始揭秘文件的神秘面纱吧!


回顾语言层面的文件

我们在C语言接触到的文件函数不知道同学们是否忘记了,如果忘记了,我们简单的回忆一下:

#include <stdio.h>
#include <stdlib.h>int main()
{FILE* fp = fopen("log.txt","w");if(fp == NULL){perror("fp");exit(1);}fclose(fp);return 0;
}

通过fopen打开文件,以w的形式对文件进行写入,对于文件操作熟悉的同学应该知道,w这个方式进行写入的话,默认是在当前目录进行写,并且,重复运行该程序,会覆盖原来的log.txt。

这是基本知识。

那么提问了:为什么系统知道要在当前目录创建文件或者是写文件呢?

这里不妨多说几句,如果我们想要在语言层面,深刻理解文件的话,是不太现实的,因为高级语言的函数肯定是和系统调用存在一定关联的,所以我们需要先回顾一下高级语言的文件操作。

那么回到最开始的问题,为什么系统知道要在当前目录创建文件呢?

我们回想,是谁运行的我们的代码?是谁打开的文件?我们?还是程序?如果是程序,程序的本质是什么?

程序的本质是进程

所以,本质上是进程打开的我们的文件,这是第一个我们需要注意的点。

那么在Linux中,我们还有一个创建文件的方式,除了使用函数,我们可以该指令:

创建文件,这是重定向符,这是我们所熟知的,那么为什么它可以重定向呢?

以及我们第一次创建之后,写入了文件,我们再次重定向一下,文件的内容就没有了,这是为什么呢?

以及,文件是不是由OS进行统一管理呢?

如果是由OS进行统一管理,那么如果管理的呢?这里答案是比较明显的,先描述再组织

对于这里的内容,我们都需要后面的知识作为补充来了解,所以,现在进入到预备知识部分。


理解文件的预备知识

文件和磁盘

在第一个大标题来说,我们已经知道我们使用高级语言的函数来调用OS后面的文件,那么高级语言的函数是如果调用文件的呢?

不出意外,它们是通过调用系统层面的函数来操纵文件的。所以本质来说,高级语言的文件操作函数都是通过封装系统调用的函数来实现文件操作的。

那么,我们能否直接通过系统调用,来实现文件操作呢?

使用和认识系统调用函数

先来简单的看上一段代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int main()
{int fd = open("test.txt",O_WRONLY | O_CREAT);if(fd < 0){perror("open");exit(-1);}return 0;
}

这是系统层面的open函数,使用了两个宏O_WRONLY| O_CREAT,open函数的返回值是int等,查看文档看详细内容:

使用2号手册可以查看,2号手册也是代表的open是一个系统调用函数,并且一大堆的头文件,还是有点麻烦的,其次,open函数可以有三个函数参数,但是对于我们刚才的代码,为什么我们传的是类似于宏的|操作呢?

不卖关子,O_CREAT就是宏,其他也是,我们可以在2号手册里面查看许多宏。

对于O_WRONLY等,为什么我们要传两个宏的或操作呢?

这里提问:

void func(int a1,int a2,int a3,int a4...)

对于一个函数来说,如果参数的数目是可变的,我们不可能就一直这么写参数吧?

除了C++的可变模板参数可以解决,Linux中我们怎么解决呢?或着说,源码里面是怎么解决的?

我们看一段代码就知道了:

void Func(int a)
{if(a&&ONE)printf("ONE\n");if(a&&TWO)printf("TWO\n");if(a&&THREE)printf("THREE\n");}int main()
{Func(ONE);Func(ONE | THREE);Func(ONE | TWO);return 0;
}

那么,我们可以将printf换成其他功能,这就是源码里面的操作,其中的参数flags,就叫做标记位。

第三个参数就好说了,就是权限而已,但是呢,我们先不带权限创建了文件之后,看看权限是什么呢?

ll之后,test甚至都标红了,前面的权限呢?就变成乱码了。这是因为我们没有设置。

所以相对来说呢,两个参数的open更多是用于已经创建好的文件进行操作的。

int main()
{int fd = open("test.txt",O_WRONLY | O_CREAT,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}

我们需要将原来的文件删除了之后,然后再设置即可.

但是有一个奇怪的现象,为什么test.txt的权限是664而不是666呢?相信对前文文件有所了解的话,就知道权限掩码,而系统中,存在一个函数,可以动态的修改掩码:

int main()
{umask(0);int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}

此时权限就正常了,但是呢,系统中的掩码:

一看还是0002,难道不影响我们动态修改吗?

请记住,就近原则

现在引入3个问题:

1. fopen的w模式,是将文件创建,如果存在,就清空。那么我们先来看看这个宏:

int main()
{umask(0);int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");exit(-1);}return 0;
}

truncate的意思就是截断,使用起来和w是一样的:

此时文件清空。

那么:

宏O_TRUNC和w模式之间的关系是什么?

2.fd的返回值有345,但是没有012,0对应的是标准输入,键盘,1和2对应的硬件都是显示器,但是1是标准输入,2是标准错误。C语言中默认打开三个流。

返回值和C语言默认打开的流的联系究竟是什么呢?

3.宏还有O_APPEND,C语言中的函数fopen的a模式代表追加,APPEND的意思也是追加。

不同的宏与不同的模式之间的联系是什么呢?

预知后事如何~请看下篇~


感谢阅读!

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

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

相关文章

COMP 9517 Computer Vision week3

目录 特征表示图像特征概念(image feature)图像特征应该具备的属性 图像特征种类颜色特征颜色直方图(Color Histogram)颜色矩(Colour moments) 纹理特征(texture features)Haralick特征局部二值模式(Local Binary Patterns, LBP)尺度不变特征变换SIFT(Scale-invariant feature …

Error while loading conda entry point: conda-libmamba-solver

问题 解决方法 conda install --solverclassic conda-forge::conda-libmamba-solver conda-forge::libmamba conda-forge::libmambapy conda-forge::libarchive

如何实现事件流操作

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了通道相关的内容,本章回中将介绍StreamProvider组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 在Flutter中Stream是经常使用的组件,对该组件的监听可void main() {///让状态栏和程序的appBar融为一体…

zotero WebDAV同步忘记密码

https://www.jianguoyun.com/#/safety 找到应用密码

thinkphp 学习记录

1、PHP配置 &#xff08;点开链接后&#xff0c;往下拉&#xff0c;找到PHP8.2.2版本&#xff0c;下载的是ZIP格式&#xff0c;解压即用&#xff09; PHP For Windows: Binaries and sources Releases &#xff08;这里是下载地址&#xff09; 我解压的地址是&#xff1a;D:\…

Gitlab flow工作流

Gitlab flow Gitlab flow 是 Git flow 与 Github flow 的综合。它吸取了两者的优点&#xff0c;既有适应不同开发环境的弹性&#xff0c;又有单一主分支的简单和便利。它是 Gitlab.com 推荐的做法。 1 上游优先 Gitlab flow 的最大原则叫做"上游优先"&#xff08;…

【408计算机考研课程】数据结构-数据结构在学什么?

前言 数据结构在学什么&#xff1f; 如何用程序代码把现实世界的问题信息化如何用计算机高效地处理这些信息从而创造价值 第一章&#xff1a;数据结构在学什么&#xff1f; 总览 什么是数据&#xff1f; 简介&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、…

el-pagination组件封装

组件使用 源代码&#xff1a; <script setup> import Pagination from /components/pagination/index.vue import {ref} from "vue";const pageNum ref(1) const pageSize ref(10) const total ref(120)function loadData() {// 加载数据 } </script>…

拓扑排序简介

拓扑排序(Topological Sort)是一种重要的图算法,用于对有向无环图(DAG, Directed Acyclic Graph)中的节点进行排序。拓扑排序的结果是一种线性序列,使得对于图中的任意一条有向边(u, v),顶点u都在顶点v之前。这种排序常用于任务调度、编译器依赖关系分析等领域。 拓…

24个AI写作秘技,助你写出震撼人心的佳作!

最近&#xff0c;许多朋友开始尝试使用AI进行写作。然而&#xff0c;他们创作的文章常常显得语言过于正式&#xff0c;不仅缺乏沉浸感&#xff0c;发送后也很容易被系统检测出重复内容。我一直强调&#xff0c;在写作过程中&#xff0c;我们不应完全依赖AI。AI只是一种工具&…

【C语言】分支与循环

文章目录 前言if语句关系操作符逻辑操作符&#xff1a;&& , || , &#xff01;switch语句if语句和switch语句的对比 while循环for循环do-while循环break和continue语句循环嵌套goto语句 前言 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是顺序结构、选择&…

12条职场经验总结

01 事干得好不好尚且不说&#xff0c;但是话一定要说得漂亮。 比如&#xff0c;当领导给你安排工作的时候&#xff0c;你一定要非常积极地响应&#xff0c;拍着胸脯跟领导说“放心吧”。至于后续到底怎么干&#xff0c;再结合实际情况有的放矢地把握。 02 当别人夸奖你的时…

Hugging Face 任意大模型仓库劫持 - 无声的破坏

摘要 在这篇博客中&#xff0c;我们展示了攻击者如何攻击Hugging Face的Safetensors转换空间及其相关的服务机器人。这些服务是一个在Hugging Face上广受欢迎的服务&#xff0c;专门用于将不安全的机器学习模型转换为更安全的版本。我们随后展示了如何通过Hugging Face自身的服…

GoogleNet原理与实战

在2014年的ImageNet图像识别挑战赛中&#xff0c;一个名叫GoogLeNet 的网络架构大放异彩。以前流行的网络使用小到11&#xff0c;大到77的卷积核。本文的一个观点是&#xff0c;有时使用不同大小的卷积核组合是有利的。 回到他那个图里面你会发现,这里的一个通过我们最大的池化…

《Linux从小白到高手》理论篇:Linux用户和组相关的命令

List item 本篇介绍Linux用户和组相关的命令&#xff0c;看完本文&#xff0c;有关Linux用户和组相关的常用命令你就掌握了99%了。Linux用户和组相关的命令可以分为以下六类&#xff1a; 一.用户和用户组相关查询操作命令&#xff1a; Id id命令用于显示用户的身份标识。常见…

职场中的10个“人情世故”,随处可见

职场上&#xff0c;“现实”是主基调。如果不通#人情世故#&#xff0c;可能举步维坚。很多时候&#xff0c;人情世故并不是什么高深的学问&#xff0c;就是在点点滴滴间&#xff0c;只要稍加注意&#xff0c;就能学通。下面这10条&#xff0c;是职场很常见的人情世故。 1、登门…

InnoDB 事务模型

文章目录 InnoDB 事务模型事务ACID特性事务隔离级别 事务操作事务并发问题事务数据读写类型Consistent Nonlocking Reads 快照读Locking Reads 加锁读 MVCC 并发控制实现原理InnoDB 隐藏列Read ViewUndo log实现过程 MVCC与隔离级别MVCC和辅助索引 幻读幻行问题可重复读MVCC会出…

HTB:Synced[WriteUP]

目录 连接至HTB服务器并启动靶机 1.What is the default port for rsync? 2.How many TCP ports are open on the remote host? 3.What is the protocol version used by rsync on the remote machine? 4.What is the most common command name on Linux to interact w…

一些关于上传数据-p7zip-full-压缩包的经验

目录 前言 7z 简介 Windows如何压缩tar.gz格式 一、下载7-ZIP 二、tar文件进一步压缩 说明&#xff1a; 前言 本人每次在linux服务器上执行apt-get install p7zip-full命令&#xff0c;都会有复杂依赖报错&#xff08;因为实验过程中用到的依赖包太多了&#xff09;&…

[Python学习日记-39] 闭包是个什么东西?

[Python学习日记-39] 闭包是个什么东西&#xff1f; 简介 闭包现象 闭包意义与作用 简介 在前面讲函数和作用域的时候应该提到过&#xff0c;当函数运行结束后会由 Python 解释器自带的垃圾回收机制回收函数内作用域已经废弃掉的变量&#xff0c;但是在 Python 当中还有一种…