Linux知识点 -- 基础IO(三)

news2024/11/25 20:36:25

Linux知识点 – 基础IO(三)

文章目录

  • Linux知识点 -- 基础IO(三)
  • 一、理解文件系统
    • 1.磁盘文件
    • 2.文件系统的存储结构
    • 3.inode与文件名的关系
  • 二、软硬链接
    • 1、软链接
    • 2.硬链接
  • 三、动静态库
    • 1.库
    • 2.生成静态库
    • 3.静态库的使用
    • 4.生成动态库
    • 5.使用动态库
    • 6.为什么要有库


一、理解文件系统

1.磁盘文件

磁盘是永久性存储介质,如:SSD,U盘,光盘,磁带等;磁盘是外设,是我们计算机中唯一的机械设备,因此读取速度很慢;

  • 磁盘物理结构:
    在这里插入图片描述
    磁盘中有盘片、磁头、伺服系统、音圈马达等;
    磁盘面上会存储数据,由于计算机只认识二进制,因此用磁极来表示0和1,向磁盘写入,本质就是改变磁盘上的正负极;

  • 磁盘存储结构:
    在这里插入图片描述
    在这里插入图片描述
    磁盘中的每一个盘面都分为多个不同的磁道,每个磁道又分为不同的扇区,磁盘的最小存储单元是一个扇区大小是512byte

  • 如何将数据写入指定的扇区?
    这是磁盘的CHS寻址:
    (1)在哪一个面上;
    (2)在哪一个磁道上;
    (3)在哪一个扇区上;

  • 磁盘的抽象结构:
    我们将磁盘的磁道展开成为线性结构:
    在这里插入图片描述
    这样来看磁盘的结构就像是一个数组,访问一个扇区,只需要知道这个扇区的数组下标就好;
    我们平常所说的磁盘分区,就是将磁盘分为几个不同的数组:
    在这里插入图片描述
    将数据存储到该磁盘就变成了将数据存储到该数组;
    找到磁盘特定扇区的位置就变成了找到数组特定的位置;
    对磁盘的管理就变成了对数组的管理;

2.文件系统的存储结构

其中一个磁盘分区展开后的结构如下:
在这里插入图片描述
其中Blokck group就是用来存储文件的;
Linux在存储文件的时候,将内容和属性分开存储;
虽然磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB(block的大小),因此,磁盘又被称为块设备;
这样设计的原因是:

  • IO基本单位设计的太小的话,会导致效率变低;
  • 如果OS使用和磁盘一样的基本单位,如果磁盘的基本单位更改了,那么操作系统也需要更改,所以需要对硬件和软件进行解耦;

在Blokck group中,有如下几个分区:

  • Super Block:存储整个分区的文件系统的属性信息;并不是每个快组都有SB模块,而是分发在分区中某几个快组中,为的是进行备份,防止丢失;
  • Group Descriptor Table(GDT)块组描述符,描述各个block的信息,如大小,使用情况,有多少inode等;
  • Block Bitmap:块组位图,其中的比特位和特定的block是一一对应的,如果该位为1,就表示该block已被占用,否则表示可用;
  • Inode Bitmap:inode位图,其中的比特位和特定的inode是一一对应的,如果该位为1,就表示该inode已被占用,否则表示可用;
  • Inode Table:inode是一个大小为128字节的空间,保存的是对应文件的属性,是该块组内,所有文件的inode空间的集合;需要标识唯一性,每一个inode块,都需要有一个inode编号,一般而言一个文件一个inode,一个inode编号;
  • Data blocks:多个4KB(扇区 * 8)大小的集合,保存的都是特定文件的内容;

格式化:将块组分割成上面的内容,并且写入相关的管理数据,每一个块组都如此操作,整个分区就被写入了文件系统信息;

一个文件可能对应多个block,找到文件,只需找到对应的inode编号,就能找到该文件的inode属性集合,文件内容所占的块组编号也在inode信息中的blocks数组中;
在这里插入图片描述
如果文件特别大,一个块组中放不下,需要存放到其他块组中,那么,inode中的blocks数组前m个block存放的是这个文件的数据,数组后面的block存放的是剩下数据存放的block块号,相当于一个间接寻址

3.inode与文件名的关系

  • Linux系统寻找文件的过程:
    由文件inode编号 -> 找到特定的bg块组 -> 对应的inode -> 属性 -> 内容;

那我们是如何得到文件的inode编号的?依托于目录结构;
Linux中,文件属性里面,没有文件名这样的说法;

  • (1)一个目录下,可以保存很多文件,但是这些文件没有重复的文件名;
  • (2)目录也是文件,有自己的inode,有自己的data block;

在Linux系统中存储文件,用户根据文件名创建和区分文件,但是写入系统时,系统只会为文件分配唯一的inode编号,然后建立文件名和inode编号的映射关系表,是一个KV结构,用户提供文件名,OS提供inode编号,所以用户能够通过文件名搜索到文件;

目录的权限:

  • 在目录中创建文件必须有写权限,是因为创建文件必须向目录写入该文件的文件名和inode的映射关系;
  • 显示文件名和属性必须有目录的读权限,因为要读取到文件的inode,才能读取属性

一个块组中,inode和data blocks的数量都是一定的,存在inode还有,但是block没了;或者inode没了,但是block还有的情况;

二、软硬链接

1、软链接

  • 创建软链接:
    在这里插入图片描述
    ln:创建链接;
    -s:软链接;

    ls -i指令能够看出文件的inode:
    在这里插入图片描述
    可以看到,软链接是有独立的inode的,是一个独立的文件;

  • 软链接的作用:
    在这里插入图片描述
    在bin/exe目录下的可执行程序test,在现在的目录下建立软链接:
    在这里插入图片描述
    直接运行软链接:
    在这里插入图片描述
    可以看出运行成功;
    软链接的文件内容,是指向对应文件的路径;可以理解为win下的快捷方式;

2.硬链接

  • 创建硬链接:
    在这里插入图片描述
    在这里插入图片描述
    可以看出,硬链接文件没有自己独立的inode,这也是软硬链接的本质区别;

  • 硬链接的作用:
    在这里插入图片描述
    从上图可以看出,硬链接和原文件属性中的这个数字都为2,这个属性是硬链接数
    硬链接就相当于给文件起别名,建立了文件名和指定inode的关系;
    当我们删除硬链接指向的文件时,硬链接inode还存在,属性中的硬链接数从2变成了1;
    在这里插入图片描述

硬链接没有独立的inode,不是一个独立的文件,创建硬链接,不是真正的创建新文件,就是在指定目录下,建立了文件名和指定inode的映射关系;
硬链接数就相当于一个引用计数,每创建一个硬链接时,引用计数就加一;当我们删除文件时,并不是把这个文件inode删除了,而是将这个文件的inode引用计数减一,当引用计数为0的时候,才真正删除;

  • 硬链接的用途:
    在这里插入图片描述
    新建一个普通文件,硬链接数是1;
    新建一个目录,硬链接数是2;

    在这里插入图片描述
    这是因为目录内部的 . 文件也影射了该目录的inode,两个硬链接,一个是自己的目录名链接inode,另一个是目录内部的 . 文件链接inode;
    在这里插入图片描述
    在test目录下再创建一个目录,可以发现test的硬链接数变为了3,这是因为ss目录中的 … 文件映射上级路径test的inode;

三、动静态库

1.库

  • 库中没有main函数;
  • 如果我只把.o和.h文件给别人,是可以使用的;
  • 静态库后缀为:.a;
  • 动态库后缀为:.so;

2.生成静态库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
生成的.o文件给别人是直接可以使用的,但是很麻烦;
在这里插入图片描述
在这里插入图片描述
静态库的生成过程就是把.o文件打包的过程;
在这里插入图片描述

  • ar:归档文件;

  • -r:替换;

  • -c:创建;

  • libhello.a:静态库文件,必须以lib开头,.a结尾;

  • 使用makefile实现自动打包:
    在这里插入图片描述

  • 库的发布:
    库的发布文件夹里需要有两个子文件夹:
    -inlcude:保存库的独有头文件;
    -lib:保存对应的库文件;

    在makefile中完成自动化创建:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.静态库的使用

在这里插入图片描述

  • (1)拷贝库文件到系统目录下:
    gcc头文件的默认搜索路径是:/usr/include
    gcc头库件的默认搜索路径是:/lib64 or /usr/lib64

    在这里插入图片描述
    这时main函数中不会报错,但是编译时会报错,因为这是我们自己提供的第三方库,必须要告知C语言我们需要连接哪个库;
    在这里插入图片描述
    -l库名:指定链接库(没有空格),真正的库名是去掉前缀lib和后缀的
    运行结果:
    在这里插入图片描述
    但是这种方法会污染官方库,不建议使用;

  • (2)让GCC在指定目录下搜索头文件和库:
    在这里插入图片描述
    -I 目录:在指令目录下搜索头文件;
    -L 目录:在指定目录下搜索库文件;
    由于该目录下可能有多个库文件,因此需要指定库文件;

    在这里插入图片描述
    在这里插入图片描述

4.生成动态库

在这里插入图片描述
在这里插入图片描述
-fPIC:生成一个与位置无关的目标二进制文件;
在这里插入图片描述
-shared:制作动态库,而不是可执行程序;

  • 用makefile实现:
    在这里插入图片描述
    动静态库一起生成,并发布output文件夹;
    在这里插入图片描述
    在这里插入图片描述
    打包库:
    在这里插入图片描述

5.使用动态库

在这里插入图片描述
从上面看出,直接使用gcc指定头文件和库文件的方法来加载动态库,能够编译过,但是无法运行程序,使用ldd命令查看动态链接时,发现libhello.so动态库链接找不到
ldd 可执行程序:查看该程序的动态链接;
我们发现gcc是默认动态链接的,但是没有链接上;
前面静态库是因为只有静态库,gcc只能静态链接:
在这里插入图片描述
使用静态库时就没有链接libhello.so;
-static:摒弃默认优先使用动态库的原则,直接使用静态库的方案;
在这里插入图片描述
在上面我们已经制定了动态库的路径,动态库还是无法链接,这是因为我们是给gcc指定的链接,这和动态库的加载过程有关;

  • 动态库的加载过程:
    动态库是一个独立的库文件,动态库和可执行程序,是可以分配加载的;
    静态库的加载是直接将库代码加载到了内存里面,直接进入进程的代码区;
    动态库是可以分批加载的,在将可执行程序加载到内存后,可执行程序中是有对应的库链接信息的;
    在编译链接时,需要加载库时,就可以加载动态库了,是分开进行的,这时再将动态库代码加载到内存中,在页表建立库代码与共享区的联系;
    在代码区函数跳转访问库函数的时候,直接跳转到共享区,根据页表找到内存中的库代码去执行;

    在这里插入图片描述

  • 方法一:添加环境变量
    我们上面指定动态库路径是给gcc指定的,动态库是运行时加载的,这时就与gcc没有关系了,需要给系统说;
    在这里插入图片描述
    $LD_LIBRARY_PATH是系统环境变量,加载库的路径;
    库的绝对路径:
    在这里插入图片描述
    导入环境变量:
    在这里插入图片描述
    运行可执行程序:
    在这里插入图片描述
    这种方法的缺点是:退出登陆后,环境变量会丢失,因为这是内存级的环境变量,只能做一个临时方案;

  • 方法二:修改配置文件
    在这里插入图片描述
    这个路径中包含自定义搜索库路径的永久解决方案;
    在这里插入图片描述
    直接创建文件,然后将目录放进该文件中;
    在这里插入图片描述
    在这里插入图片描述
    更新系统权限:
    在这里插入图片描述
    运行:
    在这里插入图片描述
    在这里插入图片描述

  • 方法三:在系统目录下建立软链接
    在这里插入图片描述
    运行:
    在这里插入图片描述

6.为什么要有库

  • 站在使用者的角度:
    库的存在,可以大大减少我们的开发周期,提高软件本身的质量;
  • 站在开发库的角度:
    简单,且能够保证代码安全;

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

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

相关文章

山西电力市场日前价格预测【2023-08-02】

日前价格预测 预测明日(2023-08-02)山西电力市场全天平均日前电价为323.97元/MWh。其中,最高日前电价为360.30元/MWh,预计出现在20: 00。最低日前电价为295.41元/MWh,预计出现在13: 30。 价差方向预测 1:实…

SQL-进阶

mysql --local-infile -u root -pset global local_infile 1;load data local infile 目录 into able 表名 fields terminated by , lines terminated by \n;

经验之谈:==和equals()如何正确使用

大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。 在Java编程中,比较两个对象是非常常见的操作。然而,初学者常常对于 和 equals() 之间的区别不够清晰,容易在使用时出错。本文将深入…

CBG9326 与HMC9326MS8G对比开发资料

国内使用UWB高精度室内定位的行业应用产品,工作频段大部分都在3.5Ghz-6GHz低频段(Channel 2(特定场景如管隧矿)和Channel 5)范围,因此只能应用于煤矿、监狱等封闭的小众市场。从市场趋势来看,业…

6.5 多维数组

6.5 多维数组 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组 如图 二维数组 int a[][] new int[2][5]这个数组a可以看成一个两行五列的数组 package com.baidu.www.array;public class ArrayDemo05…

第三人称射击项目总结

一、UML类图 二、功能需求

Qt信号与槽机制的基石-MOC详解

引入 上篇讲到了信号与槽就是实现的观察者模式,那具体如何生成映射表就是moc做的事情。 一、moc简介 1. moc的定义 moc 全称是 Meta-Object Compiler,也就是“元对象编译器”,它主要用于处理C源文件中的非标准C代码。Qt 程序在交由标准编…

使用go与智能合约交互之使用abigen生成合约go文件进行调用

前两篇文章,我们讲解了go如何通过函数选择器、abi调用的方式与智能合约交互,那么有没有一种更加便捷的方式(就好像调用预先定义好的方法一样)与智能合约交互呢?答案是有的,本章我们就来学习一下如何使用abi…

Stable Diffusion - 真人照片的高清修复 (StableSR + GFPGAN) 最佳实践

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/132032216 GFPGAN (Generative Facial Prior GAN) 算法,用于实现真实世界的盲脸恢复的算法,利用预训练的面部 GAN&#xf…

Linux和TSN网络

时间敏感网络是传统以太网的扩展,实现实时能力和确定性通信。终端通常是基于Linux OS 的,它的实时能力是通过PREEMPT-RT 补丁实现的。而设备的实时性网络是通过时间敏感性网络技术实现。到目前为止,大多数Linux OS 的TSN 都是通过特殊的解决方…

《cuda c编程权威指南》04 - 使用块和线程索引映射矩阵索引

目录 1. 解决的问题 2. 分析 3. 方法 4. 代码示例 1. 解决的问题 利用块和线程索引,从全局内存中访问指定的数据。 2. 分析 通常情况下,矩阵是用行优先的方法在全局内存中线性存储的。如下。 8列6行矩阵(nx,ny)(…

链表OJ题讲解1

💓博主个人主页:不是笨小孩👀 ⏩专栏分类:数据结构与算法👀 🚚代码仓库:笨小孩的代码库👀 ⏩社区:不是笨小孩👀 🌹欢迎大家三连关注,一起学习,一起进步&#…

MySQL高级篇第6章(索引的数据结构)

文章目录 1、为什么使用索引2、索引及其优缺点3、InnoDB中索引的推演4、MyISAM中的索引方案5、索引的代价6、MySQL数据结构选择的合理性 1、为什么使用索引 假如给数据使用 二叉树 这样的数据结构进行存储,如下图所示 2、索引及其优缺点 3、InnoDB中索引的推演 4、M…

Spring中声明式事务

声明式事务:基于Spring AOP,通过注解或XML配置实现,有助于用户将操作与事务规则进行解耦。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务…

前端小练-产品宣传页面

文章目录 前言页面结构固定钉头部轮播JS特效 完整代码总结 前言 经过一个月的爆肝,花费了一个月(期间还花费了将近半个月的时间打比赛,还要备研)算是把数二高数的内容强化了一遍,接下来刷熟练度即可,可惜的…

VirtualBox Ubuntu无法安装增强功能以及无法复制粘贴踩坑记录

在VirtualBox安装增强功能想要和主机双向复制粘贴,中间查了很多资料,终于是弄好了。记录一下过程,可能对后来人也有帮助,我把我参考的几篇主要的博客都贴上来了,如果觉得我哪里讲得不清楚的,可以去对应的博…

前端生成图片验证码怎么做?

##题记:我们实现一个功能首先想一下我们需要做哪些工作,比如我们需要生成一个随机的图片验证码,我们需要一个就是点击事件获取验证码,通过接口我们去获取图片路径进行渲染就行,这里边还要牵扯一件事情就是获取一个随机…

uniapp开发小程序-实现中间凸起的 tabbar

一、效果展示: 二、代码实现: 1.首先在pages.json文件中进行tabbar的样式和列表配置,代码如下: {"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/p…

Stable Diffusion AI绘画学习指南【本地环境搭建win+mac】

一、硬件配配置要求 系统:windows 10 / Mac os 硬盘:C 盘预留 15GB 以上,其他盘 50GB 以上,Stable Ddiffusion的很多大模型都是以 GB 起步。 显卡:4GB 以上,建议 8GB, 效率高,能玩大尺寸的图 CPU&…

Socks IP轮换:为什么是数据挖掘和Web爬取的最佳选择?

在数据挖掘和Web爬取的过程中,IP轮换是一个非常重要的概念。数据挖掘和Web爬取需要从多个网站或来源获取数据,而这些网站通常会对来自同一IP地址的请求进行限制或封锁。为了避免这些问题,数据挖掘和Web爬取过程中需要使用Socks IP轮换技术。在…