• (入门自用)--Linux--文件系统--磁盘--1019


    背景知识:没有被进程打开的文件存放在磁盘

    单个文件角度:文件位置,文件大小等属性。

    系统角度:文件数量,文件对应的属性,还可以存储多少文件等

    1. 磁盘的物理结构

    磁盘有磁盘盘片、磁头、伺服系统、音圈马达。

     

    盘片上有多个同心圆,称为磁道。

    将盘片分成很多扇形,在每一个扇形内的磁道称为扇区。每一个扇区是磁盘存储数据的基本单位,为512字节。

     

    物理上把数据写入制定扇区,需要先找到扇区。

    CHS寻址:1.在哪一个面上(对应的就是哪一个磁头)。2.在哪一个磁道上。3.在哪一个扇区上

    1. 2 磁盘的抽象结构

     

    将磁盘盘面当成卷起来的磁带,磁带抽出来就成了线性结构。扇区可以抽象理解成数组,访问一个扇区只需要知道数组下标。

    1.3 磁盘分区

     将磁盘抽象理解成线性数组之后,数据存储到磁盘起始就是存储到数组。找扇区就是找数组下标,对磁盘的管理就是对数组的管理。一个磁盘的大小非常大,所以需要分区管理(C、D盘之类的)。每一个区域都有若干块组,文件=内容+属性。Linux在磁盘上存储文件时,将内容和属性分开存储。

     虽然磁盘的基本单元是512字节,但操作系统和磁盘进行IO的基本单位是4KB,也是一个Block group(块设备)的大小。原因:1.太小会进行多次IO,降低效率。2、与磁盘进行解耦合。

    2. 块组

    Super Block文件系统的属性信息
    Date blocks

    多个(4KB )块设备的集合,包括的都是特定文件的内容

    inode Tableinode是一个大小为128字节的空间,保存的都是文件对应的属性。该块组内,所有文件的inode空间的集合,需要唯一标识性,每一个inode块,都有一个inode编号。一般一个文件,一个inode,一个inode编号。

    Block

    Bitmap

    有多于blocks个数的比特位,比特位和特定的blocks是对应的,比特位位1代表该blocks被占用,否则表示可用
    inode Bitmap同block bitmap 不过代表的是inode
    GDT块组描述符。这个块组的大小,block inode已用多少,还有多少

    2.1 inode

    1. struct inode
    2. {
    3. //文件大小
    4. //文件的inode编号
    5. //其他属性
    6. int blocks[15];
    7. };

    注意:在Linux中,inode属性里面,没有文件的文件名!

     那如果文件特别大,一个blocks才4kb存不下怎么办?其实不是所有的date block只能存文件数据,也可以存储其他块的块号。

    2.1.1 查看inode

    ls -li

    2.1.2 inode与文件名

    要想找到一个文件,需要通过他的inode编号找到分区特定的blick group,在inode table表查到对应的inode结构体,从而找到属性和内容。

    那如何得知inode编号呢?-->依托于目录结构。一个目录下可以有多个文件,但这些文件没有重复的文件名。目录也是文件,那目录的data blocks保存什么?答案是目录data blocks里面保存的是文件名。文件名和inode编号的映射关系互为Key值。

    这也是为什么在目录创建文件需要w权限

    3. 软硬链接

    3.1 软连接

    又称符号链接

    1. ln -s testLink.txt soft.link
    2. ll
    3. soft.link -> testLink.txt

    soft.link 是新建的 ,指向 testLink.txt的软连接。

    3.2 硬链接

    1. ln testLink1.txt hard.link
    2. ll
    3. hard.link

    hard.link 是新建的,指向textLink1.txt的硬链接。

    3.3 软硬链接的区别:

    硬链接没有独立的inode,相当于取别名。创建硬链接就是在指定得到目录下建立了文件名和指定inode的映射关系。当我们删除文件时,并不是把inode删掉,而是把这个文件的引用计数--,当引用计数减为0时,这个文件才真正删除。

    软连接相当于快捷方式。

    引用计数

     默认情况下,创建一个目录,其引用计数(硬链接)为2。原因是:目录名和自己目录内部有一个.文件,二者的对应的inode是一样的。                                                                                               在创建的目录路径下创建d1、d2、d3目录,该目录的硬链接数为2+3=5,原因是:d1、d2、d3目录中各有一个..文件,其代表着上级文件。


    注意:

    1.软链接可以跨文件系统,硬链接不可以。
    2.硬链接不管有多少个,都指向的是同一个I节点,会把结点连接数(引用计数)增加,只要结点的连接数不是0,文件就一直存在不管你删除的是源文件还是链接的文件。所以inode和文件名并非与是一一对应的

    只要有一个存在文件就存在。 当你修改源文件或者连接文件任何一个的时候,其他的文件都会做同步修改

    软链接不直接使用i节点号作为文件指针, 而是使用文件路径名作为指针。所以删除链接文件对源文件无影响,但是删除源文件,链接文件就会找不到要指向的文件。软链接有自己的inode, 并在磁盘上有一小片空间存放路径名。
    3.软连接可以对一个不存在的文件名进行连接 。
    4.软连接可以对目录进行连接。硬链接不可以对目录进行连接。

    4. 静态库

    静态库 .a 结尾           动态库 .so 结尾

    4.1 常规写法

     只把 .o文件给别人能用吗?

    我们用mymath.c  myprint.c 形成两个.o文件,复制到usrlib文件夹下,用main.c形成.o文件后,依然可以形成可执行程序。

    4.2  静态库

    经过上述论证,发现.o文件给其他人,编译时将自己写的main.c也形成.o文件,这三个.o文件就可以形成可执行程序。但是每次编译都需要带上.o文件,麻烦而且容易漏写,所以我们需要打包成一个文件。

    4.2.1 生成静态库

    bash: ar -rc libhello.a mymath.o myprint.o

    ar是gnu归档工具,rc表示(replace and create)

    其中hello是我这个库的名字。

    4.2.2 查看静态库中的目录列表

    bash: ar -tv libhello.a

    4.2.3 发布  Makefile

    1. libhello.a: mymath.o myprint.o
    2. ar -rc libhello.a mymath.o myprint.o
    3. mymath.o:mymath.c
    4. gcc -c mymath.c -o mymath.o
    5. myprint.o:myprint.c
    6. gcc -c myprint.c -o myprint.o
    7. .PHONY:hello
    8. hello:
    9. mkdir -p hello/lib
    10. mkdir -p hello/include
    11. cp -rf *.h hello/include
    12. cp -rf *.a hello/lib
    13. .PHONY:clean
    14. clean:
    15. rm -f *.o libhello.a

     

     4.2.4 库的使用之安装

    • 将生成的静态库拷入到需要被使用的目录下

     cp -rf hello ../usrlib

     

    • 将hello库下包含的头文件全部拷入 /usr/include/ 路径下

    sudo cp hello/include/* /usr/include/ -rf

    •  将hello库下的静态库拷入 /lib64 路径下

    sudo cp hello/lib/libhello.a /lib64

    • 编译时 需要带上我们的库名称

    gcc main.c -lhello

    4.2.5 库的使用之硬使用

    gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello

     -I 表示头文件在这里找

    -L 表示库文件在这里找

    -lhello 在特定他路径下使用hello库

     5. 动态库

    5.1 生成动态库

    形成一个与位置无关的二进制文件

    gcc -fPIC -c mymath.c -o mymath.o

    gcc -fPIC -c myprint.c -o myprint.o

    生成动态库

    gcc -shared myprint.o mymath.o -o libhello.so

     Makefile

    5.2 使用动态库

    • 动静态库同时存在时,gcc默认采用的是动态库。
    • 如果同时存在的情况下非要使用静态链接,编译时需要加 -static

     5.2.1 添加至环境变量

    查看库搜索路径 (没有设置过就是空)

    echo $LD_LIBRARY_PATH

     添加至环境变量

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:路径

     退出Xshell后设置的环境变量就没了,因为设置的是内存级的环境变量

    5.2.2 新增配置文件

    在 /etc/ld.so.conf.d/ 路径下创建一个文件,然后将路径放到该文件中,然后更新

    sudo touch /etc/ld.so.conf.d/hellolib.conf

    sudo vim /etc/ld.so.conf.d/hellolib.conf

    sudo ldconfig

     5.2.3 建立软链接

    sudo ln -s 路径/libhello.so  /lib64/libhello.so

  • 相关阅读:
    Linux c编程之UDP通信
    全新升级的AOP框架Dora.Interception[5]: 实现任意的拦截器注册方式
    Linux 一键换源脚本
    cgo+gSoap+onvif学习总结:8、arm平台交叉编译运行及常见问题总结
    Opencv | 直方图
    亚马逊是如何铺设多个IP账号实现销量大卖的?
    第六章 dubbo接口测试
    简单而高效:使用PHP爬虫从网易音乐获取音频的方法
    Web服务器概述及http协议
    MM32F0020 GPIO驱动LED灯(MM32F0020 GPIO Toggle)
  • 原文地址:https://blog.csdn.net/qq_68741368/article/details/127424403