Linux:文件系统初步理解

文章目录

  • 文件的初步理解
  • C语言中对文件的接口
  • 系统调用的接口
    • 位图的理解
    • open调用接口
  • 文件和进程的关系
    • 进程和文件的低耦合
  • 如何理解一切皆文件?

本篇总结的是关于Linux中文件的各种知识

文件的初步理解

在前面的文章中有两个观点,1. 文件 = 内容 + 属性2. Linux下一切皆文件,因此就要对这两个观点进行阐述

首先,文件 = 内容 + 属性

不管是在什么平台下进行操作文件,无非只能对两个方面进行操作,对于内容做操作,和对于属性做操作,而内容和属性实际上都是数据,举一个最简单的例子,一个空文件占用内存吗?答案是占用的,因为文件在内存中不仅要存储内容,它还要存储对应的属性

如何访问文件?

想要访问一个文件,首先要找到它,文件在哪?

文件一般而言都是存储在磁盘中的,而磁盘是属于外部设备,由冯诺依曼体系可以知道,想要访问外部设备,一定要先加载到内存中,加载到内存中才能让CPU对文件进行访问,那么这些操作是交给谁来做?答案当然是操作系统

访问文件的过程?

想要访问文件,首先要把这个文件打开,那么谁来打开?如何打开?打开前和打开后对于文件而言有什么变化呢?该如何理解打开的这个过程呢?

对于上面的这些问题,简单阐述的结果如下:

谁打开文件?答案是进程,说操作系统也不为过。进程可以对文件进行打开的操作

如何打开?在系统调用中有专门的接口用以打开文件,下面对这句进行更深入的解释

如何理解打开的过程?打开前,对于文件来说就是磁盘上的一个数据而已,但是在打开后,会把文件加载到内存中,其次可以对文件进行各种的管理

进程可以打开多个文件?

当然可以,不仅如此,文件被加载到内存中,操作系统作为内存当中的大管理者,对于文件的操作是必不可少的,那既然要管理,管理的一定就是文件的各种属性,所以根据前面对于进程的经验来看,对于文件的描述是肯定必不可少的,也就是说,文件也会和进程一样,有专门的task_struct来对它进行描述

进程想要打开这个文件,就要委托给管理者来帮它打开,而操作系统作为管理者会提供多种多样的系统调用接口,来供给进程完成它想要完成的操作

文件的分类

从文件是否被打开的角度来看,文件总体上会分为:被打开的文件和没有被打开的文件

C语言中对文件的接口

C语言中对文件的接口,下面来进行举例论证

w进行写入

// 测试文件的各种接口
void testCfile1()
{
    // 以w的方式打开文件
    FILE* fp = fopen("log.txt", "w");
    if(fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fclose(fp);
}

在这里插入图片描述
w是写的形式写入,并且会清空文件的内容:

在这里插入图片描述

a进行写入

void testCfile2()
{
    // 以a的方式打开文件
    FILE* fp = fopen("log.txt", "a");
    if(fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fclose(fp);
}

在这里插入图片描述

此时,文件内容就没有被修改了,a表示append,表示追加的意思,不会打破原始的数据

文件数据的写入

void testCfile3()
{
    // 向文件中写入信息
    FILE* fp = fopen("log.txt", "a");
    const char *msg = "hello linux\n";
    if(fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fputs(msg, fp);
    fclose(fp);
}

在这里插入图片描述

系统调用的接口

在系统接口中,一定有关于文件的系统调用,那么下面对于文件的系统调用进行一些总结:

系统调用—open

在这里插入图片描述
上面关于open系统调用中有三个参数,第一个是路径名,第二个是传递的方式,关于这个传递的方式下面进行讲解,第三个参数是打开文件时,如果需要创建文件,所创建的权限是多少

位图的原理

在这里插入图片描述
上面这些就是第二个参数所对应的一些参数,在系统调用中存在多种打开模式,比如可以只读只写等等…这些调用的接口都可以在底层系统调用中进行任意的选择,那下面首先对位图的原理进行理解:

位图的理解

#include <stdio.h>

#define Print1 1      // 0001
#define Print2 (1<<1) // 0010
#define Print3 (1<<2) // 0100
#define Print4 (1<<3) // 1000

void Print(int flags)
{
    if(flags & Print1) printf("hello 1\n");
    if(flags & Print2) printf("hello 2\n");
    if(flags & Print3) printf("hello 3\n");
    if(flags & Print4) printf("hello 4\n");
}

int main()
{
    Print(Print1);
    Print(Print1 | Print2);
    Print(Print1 | Print2 | Print3);
    Print(Print3 | Print4);
    Print(Print4);
    return 0;
}

对于上述代码就是所谓位图的理解,当传入一个参数flag之后,位图中的每一个二进制位都代表不同的值,而这个值就代表着不同的系统调用的功能,抛开函数封装不谈,上面的函数如果直观的从main函数来看,就是传入Print1,就调用Print1的功能,以此类推,因此在系统调用的接口中也和上述的原理类似,传入了什么类型的系统调用参数,那么我就执行对应的系统调用,这是一个道理

基于这个原因,就可以理解系统调用与位图的结合,共同帮助使用各种系统调用的功能,在Linux中,这种传参的方式叫做标志位传参,这也是Linux中最常用的一种传参方式,那么下面对系统调用进行更进一步的使用和理解

open调用接口

// 测试系统调用的接口
void testOS1()
{
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC);
    if(fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    close(fd);
}

上面的代码就是利用系统调用的接口来实现了一个以写的方式/创建文件/清除内容的形式来打开了一个文件,但是创建结果却异常了:

在这里插入图片描述

报红了,为什么呢?原因是因为,没有设置对应的权限值,创建一个文件,却没有给予它对应的权限,这样创建出来的文件,Linux系统不知道它是要干什么的,因此会标红提示用户进行处理,解决方案也很简单,只需要在第三个参数中给他传递对应的权限大小的参数即可

在这里插入图片描述

至于为什么没有按照想要的权限创建,这是因为Linux系统内部有其对应的权限掩码,创建的任何文件都会被权限掩码屏蔽掉对应的权限,可以在函数前设置umask(0)来解决这个问题

那么这里就初步的对文件有了基本认知,但是还有一个问题没有解决,open系统调用会返回一个int类型的数据,这个值是干什么的呢?

void testOS2()
{
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if(fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    printf("fd : %d\n", fd);
    close(fd);
}

在这里插入图片描述
这个值是3,那么这个值代表什么意思呢?

文件和进程的关系

这个3,是什么意思?如何理解3?

这个3,其实代表的是这个进程打开了多少个文件,也就是说前面还有0 1 2三个文件已经被打开了,那这三个文件是什么?

在进程启动的时候,系统会默认的为进程打开三个文件:stdin,stdout,stderr,正是因为有这三个文件,使用者才能对于任意一个进程都可以进行数据的写入和读取,这是这三个文件带来的功能

解释完3的意义,那C语言的库函数和系统调用之间究竟有什么关系呢?如何理解呢?

fopen函数是C语言库中给使用者准备好的库函数,这个库函数实际上内部封装的系统调用就是open这个系统调用,那么下面就走进内存的视角,来看进程和文件究竟是一种什么样子的关系?

进程和文件的低耦合

先画下面的一张图,根据这张图引出结论:

在这里插入图片描述
上面这张图是什么意思呢?该如何理解这张图呢?

创建了一个进程,就一定会创建进程对应的PCB文件,这是一定的,而在进程的PCB中存在一个结构体指针,这个结构体指针指向了一个叫做进程文件描述符表的结构体,而在这个结构体中,存储的是一个一个的文件描述符指针,而前面所谓的0 1 2 3实际上就是对应的下标

而进程文件描述符表中的这个结构体指针数组,每一个指针就会指向一个文件描述符,而文件描述符都会被通过某种方式链接在一起,文件描述符被创建就是当磁盘中的数据被读取到内存中时,就会为这个文件创建一个独属于它的文件描述符,这样就可以大体上把进程和文件分割开,文件隶属于文件的部分内容,进程隶属于进程的部分内容,它们之间通过一个文件的指针数组联系起来

在Linux内核源码中找内容:

PCB中含有进程描述符表的地址

在这里插入图片描述
进程文件描述符中含有文件描述符的指针数组

在这里插入图片描述
文件描述符的定义

在这里插入图片描述
文件描述符的连接情况

在这里插入图片描述
由此引出一个结论,操作系统访问文件,只识别的是文件描述符,不管通过多少次调用,最终的最终还是会识别到文件描述符

如何理解一切皆文件?

通过上面的原理,得出的初步结论是,操作系统访问文件只认文件操作符,而前面已经建立起了一些认知,例如一切皆文件,那么什么是一切皆文件?又该如何理解这句话呢?

一切皆文件

对于文件描述符中,它当中一定会包含有读选项和写选项,只有对文件可以进行读取和写入,才能正在意义上的称得上是对文件进行管理,那么问题来了,既然一切皆文件,那么对于键盘显示器网卡等等的硬件设备,该如何进行写入呢,是不是意味着它们也会有所谓的文件描述符呢?

答案是肯定的,既然被称得上是文件,那么操作系统一定可以去管理它们,既然可以去管理它们,那么操作系统一定会为它们建立文件描述符,所以不管是什么硬件,每一个硬件都会有它所对应的文件描述符方便于操作系统进行管理

硬件的读写方法是根据不同的硬件肯定是不一样的,那么对于每一个硬件都会有它独属的读取和写入的函数方法,在有了对应硬件的读写方法后,就通过函数指针的方式写入了硬件所对应的文件描述符中,这样就可以在硬件的文件描述符中找到它所专属于的写入和读取的方法,进而进行一系列调用,这样就能把硬件和软件连接在一起

VFS–虚拟文件系统

在文件系统中,可以把硬件对应的文件描述符看成是一种虚拟的文件系统,通过这样的文件系统可以近似的把硬件设备的各种信息转换到内存中方便于进行管理,而这个虚拟文件系统和对应的调用方法之间的关系,就有些类似于基类和子类的关系,这是不是就是所谓的多态呢?对于不同的内容可以使用不同的方式进行调用,进而实现不同的功能

通过上面的理解,其实已经对一切皆文件这个概念有了进一步的认知,一切皆文件,不管是硬件层面还是软件层面,即使是用户肉眼可以看到的键盘显示器等等,操作系统也会把他们当成文件来处理,处理的方式就是对它们建立对应的文件描述符,而文件描述符中含有的函数指针会近似于用一种多态的方式实现对硬件的读取和写入的功能,这样就实现了对硬件的资源管理

现在就可以理解,为什么进程在运行的时候,会默认打开三个文件:标准输入,标准输出,标准错误文件流了!这样就可以保证在编写程序的时候,可以使用默认的代码进行编写

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

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

相关文章

手撕A*算法(详解A*算法)

A*算法原理 全局路径规划算法&#xff0c;根据给定的起点和终点在全局地图上进行总体路径规划。 导航中使用A*算法计算出机器人到目标位置的最优路线&#xff0c;一般作为规划的参考路线 // 定义地图上的点 struct Point {int x,y; // 栅格行列Point(int x, int y):x(x),y(y){…

51单片机利用I/O口高阻状态实现触摸控制LED灯

51单片机利用I/O口高阻状态实现触摸控制LED灯 1.概述 这篇文章介绍使用I/O口的高阻状态实现一个触摸控制LED灯亮灭的实验。该实验通过手触摸P3.7引脚&#xff0c;改变电平信号控制灯的亮灭。 2.实验过程 2.1.实验材料 名称型号数量单片机STC12C20521LED彩灯无1晶振12MHZ1电…

PDF 批量处理软件BatchOutput PDF mac中文版介绍

BatchOutput PDF mac是一款适用于 Mac 的 PDF 批量处理软件。它可以帮助用户将多个 PDF 文件进行异步处理&#xff0c;提高工作效率。 BatchOutput PDF 可以自动化执行许多任务&#xff0c;包括 PDF 文件的打印、转换、分割、压缩、加密、重命名等&#xff0c;而且它还可以将自…

开启数据库审计(db,extended级别或os级别),并将审计文件存放到/home/oracle/audit下

文章目录 开启数据库审计&#xff08;db,extended级别或os级别&#xff09;&#xff0c;并将审计文件存放到/home/oracle/audit下一. 简介二. 配置2.1. 审计是否安装2.2. 审计表空间迁移2.3. 审计参数2.4. 审计级别2.5. 其他审计选项2.6. 审计相关视图 三. 使用3.1. 开启/关闭审…

案例023:基于微信小程序的童装商城的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie,C#后台执行js

目录 框架信息&#xff1a;MainWindow.xamlMainWindow.xaml.cs爬取逻辑模拟登录拦截请求Cookie获取 CookieVisitorHandle 框架信息&#xff1a; CefSharp.OffScreen.NETCore 119.1.20 MainWindow.xaml <Window x:Class"Wpf_CHZC_Img_Identy_ApiDataGet.MainWindow&qu…

关于前端上传

类似于 上面的传参form-data形式&#xff0c;第一个参数为上传的文件&#xff0c;第二个参数为json格式

Centos部署GitLab-备份恢复

1. 下载rpm包 wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.8.4-ce.0.el7.x86_64.rpm2. 安装依赖 yum -y install policycoreutils openssh-server openssh-clients postfix policycoreutils-python3. rpm安装 rpm -ivh gitlab-ce-10.8.4-ce.…

OpenStack云计算平台

目录 一、OpenStack 1、简介 2、硬件需求 3、网络 二、环境搭建 1、安全 2、主机网络 3、网络时间协议(NTP) 4、OpenStack包 5、SQL数据库 6、消息队列 7、Memcached 一、OpenStack 1、简介 官网&#xff1a;https://docs.openstack.org/2023.2/ OpenStack系统由…

git查看某个commit属于哪个分支方法(如何查看commit属于哪个分支)

有时候&#xff0c;当我们由于业务需求很多时&#xff0c;基于同一个分支新建的项目分支也会很多。 在某个时间节点&#xff0c;我们需要合并部分功能点时&#xff0c;我们会忘了这个分支是否已经合入哪个功能点&#xff0c;我们就会查看所有的commit记录&#xff0c;当我们找到…

Jmeter快速入门

文章目录 1.安装Jmeter1.1.下载1.2.解压1.3.运行 2.快速入门2.1.设置中文语言2.2.基本用法 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址&#xf…

Word中如何实现 图片 | 表格 自动编号与文中引用编号对应

当我们在进行大篇幅word文档的编写时&#xff0c;为了节约修改文章中图片或表格所花费的大量时间&#xff0c;可以将图片自动编号&#xff0c;且让文中引用的顺序跟着图片顺序的变化而变化&#xff0c;具体操作如下&#xff1a; 1. 将鼠标定位在图片或者表格欲加编号的下方或上…

【SpringBoot3+Vue3】五【完】【实战篇】-前端(配合后端)

目录 一、环境准备 1、创建Vue工程 2、安装依赖 2.1 安装项目所需要的vue依赖 2.2 安装element-plus依赖 2.2.1 安装 2.2.2 项目导入element-plus 2.3 安装axios依赖 2.4 安装sass依赖 3、目录调整 3.1 删除部分默认目录下文件 3.1.1 src/components下自动生成的…

2.HTML入门

目录 一.HTML介绍 二.HTML常用标签 2.1 标题标签 2.2 段落标签 2.3 超链接标签 2.4 图片标签 2.5 换行与空格 2.6 布局标签 2.7 列表标签 2.8 表单标签 一.HTML介绍 定义&#xff1a;将内容显示在网页&#xff0c;用来描述网页的一种语言&#xff0c;负责网页的架构…

objdump反汇编文件解析

命令使用 objdump可以对可执行文件进行反汇编 其常用参数为: objdump -d <file(s)>: 将代码段反汇编&#xff1b;objdump -S <file(s)>: 将代码段反汇编的同时&#xff0c;将反汇编代码与源代码交替显示&#xff0c;编译时需要使用-g参数&#xff0c;即需要调试信…

常见树种(贵州省):014槭树、梧桐、鹅掌楸、檫木、梓木、油桐、泡桐、川楝、麻楝

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、色木槭…

机器学习笔记 - 复杂任务的CNN组合

基础CNN架构可通过多种方式进行组合和扩展,从而解决更多、更复杂的任务。 1. 分类和定位 在分类和定位任务中,你不仅需要说出在图像中找到的物体的类别,而且还需指出物体显现在图像中的边界框坐标。这类任务假设在图像中只有一个物体实例。 这个任务可通过在典型的分类网络…

Cobalt Strike的各类反向上线操作

声明&#xff1a;本文仅限于技术讨论与分享&#xff0c;严禁用于非法途径。若读者因此作出任何危害网络安全行为后果自负&#xff0c;与本号及原作者无关。 前言 Cobalt Strike 使用 GUI 框架 SWING&#xff08;一种java GUI的库&#xff09;开发&#xff0c;攻击者可通过CS木马…

如何使用VisualSVN在Windows系统上设置SVN服务器并公网远程访问

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学…

常见树种(贵州省):013桉树、米槠、栲类

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、桉树 …