当前位置: 首页 > news >正文

Linux_文件系统

假定外部存储设备为磁盘,文件如果没有被使用,那么它静静躺在磁盘上,如果它被使用,则文件将被加载进内存中。故此,可以将文件分为内存文件和磁盘文件。

  • 内存文件
  • 磁盘文件
  • 软、硬链接

一.内存文件

1.1 c语言的文件接口
  • fopen:FILE *fopen(const char *path, const char *mode);
    • mode:
      • r :读方式
      • w:写,打开即清空文件
      • a:追加方式
  • fclose:int fclose(FILE *fp);
  • fwrite:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • fgets:char *fgets(char *s, int size, FILE *stream);
  • fputs:int fputs(const char *s, FILE *stream);
  • snprintf:int snprintf(char *str, size_t size, const char *format, …);

在这里插入图片描述

1.2 系统接口

1.2.1 open

image.png

  • 返回值:返回一个文件描述符(下文讨论)
  • pathname:指定文件路径
  • flags:位图,可以用宏来指定打开方式
    • O_RDONLY:读方式
    • O_WRONLY: 写方式
    • O_CREAT: 不存在则创建
    • O_TRUNC: 打开后会清空文件
    • O_APPEND:追加方式打开,不清空文件
  • mode :指定创建文件时的起始权限
// 1.读时的open写法
int fd = open("log.txt", O_RDONLY);// 2.清空写时的open写法
int fd1 = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC);//3.追加写时的open写法
int fd2 = open("log.txt", O_WRONLY | O_CREAT | O_APPEND);

当一个进程要打开文件时,操作系统将文件的属性加载到内存中,根据这些属性创建一个struct file结构体,并且将该结构体与进程控制块task_struct建立联系。

1.2.2 close

image.png

  • fd : 文件描述符,open返回值。
1.2.3 write

image.png

  • count:写入字节数
1.2.4 readimage.png

image.png

1.3 文件描述符-file descriptor

操作系统将文件加载进内存,创建对应的struct file 结构体,并且与struct task_struct建立联系。在Linux中,task_struct 内部有一个 struct files_struct 字段,这个结构体里面有struct file* fd_array[]数组,file descriptor就是这个数组的下标。如图:
image.png

1.3.2 文件描述符本质

文件描述符的本质就是struct file*fd_array 数组中的下标,当操作系统创建文件结构体struct file时,将该结构体地址填入数组中,至此进程与文件建立了联系。

  • 操作系统从开始扫描数组,遇到空位置,则填入地址,给调用进程返回数组下标,即文件描述符。

    image.png
    观察上面代码,发现文件描述符是从3开始的,这是因为c语言中默认打开三个文件,标准输入-stdin,标准输出-stdout,标准错误-stderr,它们对应数组的 0 1 2,stdout和stderr默认都指向显示器。
    image.png

1.4 struct file 与 struct FILE

struct file是内核级别的结构体,而struct FILE是c语言库中定义的结构体,这两者之间没有任何关系。
struct FILE内部有一个文件描述符int fd; 字段。当进程读写文件时,os会根据文件描述符找到对应的struct file结构体,然后进行读写操作。
image.png

1.5 重定向

重定向有三种:输出重定向,追加重定向,输入重定向

  • 输出重定向:我们可以在命令行中输入命令ls . > text,这样原本打印在显示器上的消息就打印到文本text中了,这叫做输出重定向。
  • 追加重定向:输出重定向会先清空文件,然后写入内容,追加重定向不清空文件,在文件末尾追加内容
  • 输入重定向:在命令行中输入cat < text,原本是从键盘读取字符,然后重定向到从text中读取字符 ,这就是输入重定向。

为什么ls . > text可以将打印到显示器上的数据打印到text中的呢?在Linux中,命令ls是一个程序,它也是用c语言编写的,所以是用printf来进行打印的,而printf默认会打印到stdout对应的文件中,stdout中的fd为1,如果我们将数组下标为1的元素内容从显示器改变为目标文件,那么这样就做到了将打印到显示器上的数据打印到text中。输入重定向也是同理,改变文件描述符的指向即可。即:重定向的原理就是改变数组元素的指向。这种改变是上层无法获知的,所以stdout依旧认为它对应的文件是显示器。
image.png

1.5.1 重定向的三种方式
  1. 命令行

./test > text 2>&1 : 将test的执行结果输出到text中,并且将1号文件描述符的内容靠别到2号文件描述符中,即,stderr也会输出到text中
./test 1>log 2>err :将标准输出改变为log,标准错误改变为err

  1. dup2(int oldfd, int newfd);
  • 例如dup2(3, 2); 将3号文件描述符的内容拷贝到2号文件描述符中
  1. 先关闭1号文件描述符,然后调用open
close(1);
int fd = open("log.txt", O_WRONLY|O_CREAT|_TRUNC);     // 1

1.6 内核级缓冲区和用户级缓冲区

c语言库中struct FILE结构体中有一个缓冲区,用来暂存数据,这个缓冲区叫做用户级缓冲区。内核结构体struct file 中有一个缓冲区,用来暂存数据,这个缓冲区叫做内核级缓冲区。缓冲区的目的是为了提高IO效率。
用户级缓冲区的刷新策略:‘

  1. 无缓冲
  2. 行缓冲(显示器) :遇到换行符将数据刷新到内核级缓冲区
  3. 全缓存(普通文件):当缓冲区满了才将数据刷新到内核级缓冲区

内核级缓冲区的刷新策略由os系统决定,当然我们可以调用fsync()强制刷新。

1.6.1 数据流动方式

当程序调用printf函数时,先将字符串拷贝到用户缓冲区,然后结合相关刷新策略,调用write函数将字符串从用户缓冲区拷贝到内核缓冲区,最后os结合刷新策略将数据刷新到外设中,这就是数据的流动方式。共经历三次拷贝。
image.png

1.6.2 代码示例-缓冲区
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>int main()
{//  情况1printf("hello world!\n");//  情况2  printf("hello world!");const char* msg = "tieite\n"; write(1,msg, strlen(msg)), fork();return 0;
}
  1. 情况1:输出结果:image.png
  2. 情况2:输出结果:image.png

为什么会有这样奇怪的结果呢?这与缓冲区的刷新策略有关?因为printf默认输出到显示器,而显示器的刷新策略是行刷新,所以情况1正确执行。而情况2中,没有换行符,所以数据留在用户缓冲区中,没有刷新到内核缓冲区,等调用fork的时候,创建子进程,子进程又继承了父进程的代码和数据,故此就有了两份数据“hello world!”当父子进程退出时,都会刷新用户缓冲区,于是内核缓冲区中就有两份hello world。

二.磁盘文件

2.1 磁盘

磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘(Floppy Disk,简称软盘),如今常用的磁盘是硬磁盘([Hard disk](https://baike.baidu.com/item/Hard disk/2806058?fromModule=lemma_inlink),简称硬盘)。现在的pc大部分都用的是SSD固态硬盘(电)。

2.2 磁盘的物理结构

image.png

  • 磁盘中有许多盘片,每一个盘片都有两个盘面,盘面上有若干磁道,磁道由若干扇区组成,磁盘的基本存储单元是扇区(512字节),多个盘片同半径的所有磁道构成一个柱面

image.png

2.3 硬件寻址方法-CHS

确定一个扇区的方式:先定位在哪个盘面上(磁头head),然后在定义哪个柱面cylinder(磁道),最后根据扇区(sector)编号即可定位某一个扇区。这种寻址方法也叫做CHS定位法。

2.4 操作系统寻址方式-LBA

操作系统的寻址方式和硬件的寻址方式需要解耦合,所以操作系统需要有一套新的地址。os将盘面逻辑抽象成线性的(类似以前的那种磁带全部展开后)。
image.png
将这样的结构看作一个数组,每一个扇区占一个数组下标,这样就可以轻易的获取每个扇区的地址。但是操作系统一次IO的基本单位是块(4KB),所以将8个扇区看作一个块,然后重新抽象得到下图。下面这样的地址叫做LBA-逻辑块地址。磁盘也叫做块设备,以块为单位进行IO。
image.png

2.5 磁盘分区管理

我们电脑上只带有一块盘,但是为了更好的管理,所以将盘分为若干区,为了更好的管理一个区(区等同于c盘,d盘),又将区分为若干组。每个组内有许多字段。
image.png
Linux是将文件内容和属性分开存储的。

  • Boot Block:存储了OS系统镜像以及开机启动的一些程序。
  • Super Block(SB):存储了当前区的文件系统相关的属性,如文件系统名字,整个分区的情况,非常重要,损坏的话一个分区全部不能用,因此要在每个分组内做备份。Linux用的Ext系列的文件系统。
  • Group Descriptor Table(GDT):存储了整个分组的情况
  • Block Bitmap:位图结构,分别对应Data Blocks中的块是否可用
  • Inode Bitmap:位图结构,对应Inode Table中的Inode是否有效
  • Inode Table:存储文件属性。文件属性的集合叫做Inode节点,每一个Inode节点都有一个Inode编号(文件id)。struct Inode{ int inode_num ; int block[NUM];///....};
  • Data Blocks:存储文件内容,为了建立文件属性和内容的联系,故此每个Inode节点里面都有一个数组,指明哪个块是属于本文件,可用建立直接映射,二级映射,三级映射。

os查找文件:
ls -li :查看当前目录下所有文件的inode编号

  1. 先找到文件对应的Inode编号
  2. 在Inode Table中找到Inode节点
  3. 根据Inode节点获得其内容块的地址、

2.6 Inode节点
struct inode
{int inode_number;    //inode 编号int ref_count;       // 硬链接数int modes;           //权限size_t uid;size_t size;//....int databloacks[NUM];  //内容
};
  • inode里面并没有文件名,因为操作系统并不需要文件名来标识文件,而是通过inode_编号来标识文件的。文件名只是给用户看的。
  • 我们用touch命令的时候,是os先遍历访问InodeBitmap寻找空闲的Inode Table,创建Inode,然后在当前目录下用Inode编号和文件名建立一个映射关系。目录也是一个文件,目录里面存储的是文件名和Inode编号的映射关系
  • 增删查改文件都是先根据文件名找到Inode编号

三.软、硬链接

3.1 软链接

ln -s myfile myfile-soft

  • myfile-soft为myfile的链接文件,这个链接文件的内容为myfile的路径。
  • 软链接的作用:便于执行程序,类似于Windows中的桌面快捷方式

image.png

3.2 硬链接

ln myfile myfile-hard

  • 给myfile建立一个硬链接文件myfile-hard

image.png
功能:
Linux下,每一个目录下都有两个特殊目录. .. ,一个点代表当前路径,两个点代表上级路径,为什么呢?因为一个点是当前路径的硬链接,两个点是上级路径的硬链接。这两个特殊路径使得路径切换更加容易。

  • Linux下,不容许用户给目录建立硬链接,防止出现环路问题,而. .. 是操作系统可用识别的特殊路径。

image.png

3.3软硬链接的区别
  • 通过观察创建的文件inode编号,可用知道硬链接并没有新建inode节点,而是和myfile指向同一个节点
  • 软链接新建了一个文件,其有自己的inode节点和内容
  • 硬链接数:类似于引用计数,当值为0的时候,就会释放inode节点。

image.png

相关文章:

Linux_文件系统

假定外部存储设备为磁盘&#xff0c;文件如果没有被使用&#xff0c;那么它静静躺在磁盘上&#xff0c;如果它被使用&#xff0c;则文件将被加载进内存中。故此&#xff0c;可以将文件分为内存文件和磁盘文件。 内存文件 磁盘文件 软、硬链接 一.内存文件 1.1 c语言的文件接口 …...

算法沉淀——链表(leetcode真题剖析)

算法沉淀——链表 01.两数相加02.两两交换链表中的节点03.重排链表04.合并 K 个升序链表05.K个一组翻转链表 链表常用技巧 1、画图->直观形象、便于理解 2、引入虚拟"头节点" 3、要学会定义辅助节点&#xff08;比如双向链表的节点插入&#xff09; 4、快慢双指针…...

Flink从入门到实践(一):Flink入门、Flink部署

文章目录 系列文章索引一、快速上手1、导包2、求词频demo&#xff08;1&#xff09;要读取的数据&#xff08;2&#xff09;demo1&#xff1a;批处理&#xff08;离线处理&#xff09;&#xff08;3&#xff09;demo2 - lambda优化&#xff1a;批处理&#xff08;离线处理&…...

python分离字符串 2022年12月青少年电子学会等级考试 中小学生python编程等级考试二级真题答案解析

目录 python分离字符串 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python分离字符串 2022年12月 python编程等级考试级编程题 一、题目要…...

Excel练习:折线图突出最大最小值

Excel练习&#xff1a;折线图突出最大最小值 ​​ 要点&#xff1a;NA值在折现图中不会被绘制&#xff0c;看似一条线&#xff0c;实际是三条线。换成0值和""都不行。 ‍ 查看所有已分享Excel文件-阿里云 ‍ 学习的这个视频&#xff1a;Excel折线图&#xff0c…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之MenuItem组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之MenuItem组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、MenuItem组件 用来展示菜单Menu中具体的item菜单项。 子组件 无。 接口 Men…...

Mockito测试框架中的方法详解

这里写目录标题 第一章、模拟对象1.1&#xff09;①mock()方法&#xff1a;1.2&#xff09;②spy()方法&#xff1a; 第二章、模拟对象行为2.1&#xff09;模拟方法调用①when()方法 2.2&#xff09;模拟返回值②thenReturn(要返回的值)③doReturn() 2.3&#xff09;模拟并替换…...

Atcoder ABC339 A - TLD

TLD 时间限制&#xff1a;2s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例输入1】 atcoder.jp【样例输出1】 jp【样例说明…...

企业级DevOps实战

第1章 Zookeeper服务及MQ服务 Zookeeper&#xff08;动物管理员&#xff09;是一个开源的分布式协调服务&#xff0c;目前由Apache进行维护。 MQ概念 MQ&#xff08;消息队列&#xff09;是一种应用程序之间的通信方法&#xff0c;应用程序通过读写出入队列的消息&#xff0…...

C++中的new和delete

1.new和delete的语法 我们知道C语言的内存管理方式是malloc、calloc、realloc和free&#xff0c;而我们的C中除了可以使用这些方式之外还可以选择使用new和delete来进行内存管理。 new和delete的主要语法如下 从上面的代码我们只能知道new要比malloc好写一些&#xff0c;但是其…...

rtt设备io框架面向对象学习-dac设备

目录 1.dac设备基类2.dac设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 1.dac设备基类 此层处于设备驱动框架层。也是抽象类。 在/ components / drivers / include / drivers 下的dac.h定义了如下dac设备基类 struct rt_da…...

腾讯云幻兽帕鲁服务器配置怎么选择合适?

腾讯云幻兽帕鲁服务器配置怎么选&#xff1f;根据玩家数量选择CPU内存配置&#xff0c;4到8人选择4核16G、10到20人玩家选择8核32G、2到4人选择4核8G、32人选择16核64G配置&#xff0c;腾讯云百科txybk.com来详细说下腾讯云幻兽帕鲁专用服务器CPU内存带宽配置选择方法&#xff…...

796. 子矩阵的和

Problem: 796. 子矩阵的和 文章目录 思路解题方法复杂度Code 思路 这是一个二维前缀和的问题。二维前缀和的主要思想是预处理出一个二维数组&#xff0c;使得每个位置(i, j)上的值表示原数组中从(0, 0)到(i, j)形成的子矩阵中所有元素的和。这样&#xff0c;对于任意的子矩阵(x…...

如何在 Python 中处理 Unicode

介绍 Unicode 是世界上大多数计算机的标准字符编码。它确保文本&#xff08;包括字母、符号、表情符号&#xff0c;甚至控制字符&#xff09;在不同设备、平台和数字文档中显示一致&#xff0c;无论使用的操作系统或软件是什么。它是互联网和计算机行业的重要组成部分&#xf…...

CSDN文章导出PDF整理状况一览

最近CSDN有了导出文章PDF功能&#xff0c;导出的PDF还可以查询&#xff0c; 因此&#xff0c;把文章导出PDF&#xff0c;备份一下自己的重要资料。 目前整理内容如下 No.文章标题整理时间整理之后 文章更新Size &#xff08;M&#xff09;10001_本地电脑-开发相关软件保持位…...

jmeter-05变量(用户定义变量,用户参数,csv文档参数化)

文章目录 一、jmeter有三种变量二、用户定义变量(这个更多的可以理解为全局变量)1、设置2、引用三、用户参数(可以理解为局部变量)1、设置2、引用3、用户参数化要配合线程组的线程数使用4、结果五、csv文档参数1、创建csv文件2、设置2、引用csv文件可以配合线程组的线程数,…...

CSS之水平垂直居中

如何实现一个div的水平垂直居中 <div class"content-wrapper"><div class"content">content</div></div>flex布局 .content-wrapper {width: 400px;height: 400px;background-color: lightskyblue;display: flex;justify-content:…...

2.8日学习打卡----初学RabbitMQ(三)

2.8日学习打卡 一.springboot整合RabbitMQ 之前我们使用原生JAVA操作RabbitMQ较为繁琐&#xff0c;接下来我们使用 SpringBoot整合RabbitMQ&#xff0c;简化代码编写 创建SpringBoot项目&#xff0c;引入RabbitMQ起步依赖 <!-- RabbitMQ起步依赖 --> <dependency&g…...

Unity学习笔记(零基础到就业)|Chapter02:C#基础

Unity学习笔记&#xff08;零基础到就业&#xff09;&#xff5c;Chapter02:C#基础 前言一、复杂数据&#xff08;变量&#xff09;类型part01&#xff1a;枚举数组1.特点2.枚举&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;申明枚举变量&#xff08;3&#xff…...

容器化的基础概念:不可变基础设施解释:将服务器视为乐高积木,而非橡皮泥。

不可变基础设施解释&#xff1a;将服务器视为乐高积木&#xff0c;而非橡皮泥。 想象一下用乐高积木代替橡皮泥进行搭建。使用橡皮泥时&#xff0c;您可以直接塑形和改变它。而使用乐高积木&#xff0c;您需要逐个零件搭建特定结构&#xff0c;并在需要时整体替换它们。这就是…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...