基础IO(下)——Linux

news/2024/5/20 23:22:47/文章来源:https://blog.csdn.net/Ll_R_lL/article/details/127738313

文章目录

  • 1. 理解文件系统
    • 1.2 背景知识
    • 1.2 inode vs 文件名
    • 1.3 软硬链接
  • 2. 动态库和静态库
    • 2.1 静态库.a
      • 2.1.1 如果想写一个库?(编写库的人的角度)
      • 2.1.2如果我把库给别人,别人怎么用呢?(使用库的人的角度)
    • 2.2 动态库.so
      • 2.2.1站在制作库工程师的角度——动态库
      • 2.2.2 站在一个使用者(程序员)角度——使用动态库
    • 为什么要有库?

1. 理解文件系统

1.2 背景知识

1.有没有一些被打开的文件吗?在哪里?
有。在磁盘里。磁盘级文件

2.我们学习磁盘级别的文件,我们的侧重点在哪里?
衍生问题:
单个文件角度——这个文件在哪里?这个文件多大?这个文件的其他属性是什么?……
系统角度——一共有多少个文件?各自属性在哪里?如何快速找到?我还可以存储多少个文件?如何快速的找到指定的文件?……
如何进行对磁盘文件进行分门别类的存储,用来支持更好的存取?

3.磁盘文件——了解磁盘
内存——掉电易失存储介质
磁盘——永久性存储介质(不止是磁盘)——SSD(固态硬盘)(现在笔记本上应该都是这个,但贵)、U盘、flash卡、光盘、磁带
结论:磁盘是一个外设,同时还是我们计算机中唯一的一个机械设备——慢!(对比出来的)——所以OS一定会有一些提速的方式

4.磁盘结构
物理结构:
磁盘盘片、磁头、伺服系统、音圈马达……
盘面上会存储数据——计算机只认识二进制(两态)——南极北极、有电没电、正负——向磁盘写入,本质就是改变磁盘上的正负性——磁头来改变
磁盘寻到的过程
 
存储结构:
磁道,扇区,柱面
扇区是磁盘存储的基本单位 512字节 4KB 硬件上的
在物理上,如何把数据写入到指定的扇区里?——本质就是如何找到一个扇区?
1.确定在哪一个面上(对应的就是确定哪一个磁头)
2.在哪一个磁道(柱面)上
3.在哪一个扇区上
这就是CHS寻址
如果我们有了CHS,就能找到任意一个扇区,那么所有的扇区我们都能找到。
 
抽象结构:(虚拟、逻辑)结构
磁盘盘片:圆形结构——线性结构
sector disk[10241024n];数组
访问一个扇区,只要知道数组的下标
把磁盘想像成一个大数组

将数组存储到磁盘——将数据存储到该数组
找到磁盘特定扇区的位置——找到数组特定的位置
对磁盘的管理——对该数组的管理

对磁盘的管理——对一个小分区的管理——继续分区
boot block——block group 0—— ——block group n
block group n:
super block——group descirptor table ——block bitmap——inode bitmap——inodetable——data blocks
虽然磁盘的基本单位是扇区(512字节),但是OS(文件系统)和磁盘进行IO交互的基本单位是:4KB(8*512字节)。——block大小——磁盘:块设备。
为什么不以512字节为单位呢?
1.太小。会导致多次IO,进而导致效率的降低
2.如果os使用和磁盘一样的大小,万一磁盘的基本大小变量的话,os的源代码也要改。所以硬件和软件(os)需要进行解耦。

文件 = 内容+属性
linux在磁盘上存储文件的时候,是将内容和属性分开存储(管理)的。

  • 超级块(Super Block):存放文件系统本身的结构信息。文件系统的属性信息 Data
  • blocks:多个4KB(扇区*8)大小的集合,保存的都是特定文件的内容 inode
  • Table:inode是一个大小为128字节的空间,保存的是对应文件的属性。该组块内,所有文件的inode空间的集合,需要标识唯一性,每一个inode块,都要有一个inode编号!一般而言,一个文件,一个inode,一个inode编号
  • BlockBitmap:假设有10000+个blocks,10000+比特位:比特位和特定的block是一一对应的,其中比特位为1,代表该block被占用,否则表示可用
  • inode Bitmap:假设有10000+个inode结点,就有10000+个比特位,比特位和特定的inode是一一对应的,其中比特位为1表示inode被占用,否则表示可用。
  • Group Descriptor Table(GDT):快组描述符,这个快组多大,已经使用多少了,有多少个inode,已经占用了多少个,还剩多少,一共有多少个block,使用了多少……
    这些都是能够让一共文件的信息可追溯,可管理
    格式化

一个文件只对应一共inode属性节点,inode编号
一个文件只能有一个block吗?不一定

1.哪些block属于同一个文件?
inode里面定义了一个数组,里面可以保存块的编号

struct inode
{//文件的大小//文件的inode编号//其他属性int blocks[15];}blocks[0] = 6;
blocks[0] = 7;
blocks[0] = 8;

2.找到文件,只要找到文件对应的inode编号就可以找到该文件的inode属性集合,可是文件的内容呢?
也是通过数组,映射表,找到

3.那如果这个文件特别大怎么办?
data block中,不是所有的data block只能存文件数据,它也可以存其他块的块号——间接索引——找到大量的块——类似多叉树结构(二级、三级)

 

1.2 inode vs 文件名

df -h查看 分区
找到文件:inode编号——分区特定的bg——inode——属性——内容

怎么知道inode编号?
我们之前打开文件一直用的是文件名
linux中,inode属性里面,没有文件名这样的说法!
补充知识:
1.一个目录下,可以保存很多文件,但是这些文件都没有重复的文件名!
2.目录是文件吗?是——有自己的inode,有自己的data block——data block里存的是文件名与inode编号的映射关系。两者互为key值
3.进入目录(需要x权限)——创建文件(需要w权限)——显示文件名与属性(r权限)
所以inode编号是依托于目录结构的

创建文件,系统做了什么?
根据文件系统在整个分区SuperBlock找到目录所对应的分区与块组——确定文件存储的块——去inodeBitmap里遍历位图,找到0的比特位置为1,同时拿到了一个inode号(遍历的时候做一个计数器不断累加)——拿到了inode编号——在inodeTable里把属性写进去(编号,文件权限,拥有者所属组,时间,大小……)——因为是新文件,是空的,将datablock映射的数组全部置为0
文件名:用户
inode:filesystem
创立映射关系

删除文件,系统做了什么?
找到目录对应的data block——以文件名作为key值去找到对应的inode的——将inodeBitmap对应的比特位由1置0,blockBitmap数据块的位图由1置0——再将文件名与inode的映射关系去掉
只需要将文件内容设置为无效,没有做覆盖。
无论是linux还是Windows删了都能恢复——删除日志
前提:inode编号,没有被使用,inode和datablock没有被重复占用
所以重要文件被删除之后,什么都不要做,不然会误覆盖

查看文件,系统做了什么?
目录——inodetable——datablock——文件名:inode

分区,格式化——在磁盘写入文件系统
inode是固定的,datablock是固定的
系统还有空间,但是创建文件失败:
inode还有,但是没有数据块了
数据块还有,但是没有inode了

1.3 软硬链接

ls -li
显示文件属性和inode编号

软链接有自己独立的inode——413
硬链接的inode——340

区别:有没有独立的inode
1.软链接有自己独立的inode——软链接是一个独立的文件
特性:软链接的文件内容是指向的文件对应的路径
应用:相当于Windows中的快捷方式
 
2.硬链接没有独立的inode——硬链接不是一个独立的文件0
创建硬链接不是真正的创建新文件——只是在指定目录下,建立了文件名和指定inode的映射关系
属性链接关系数字:1——2——1(硬链接数)
当我们删除一个文件的时候,并不是把这个文件的inode删除,而是将这个文件的inode引用计数–,当引用计数为0的时候,这个文件才被真正的删除——为0时就是没有文件名与其关联——没有用户关心这个文件了

为什么创建一个文件,硬链接数默认是1——一条关系
空目录默认是2——目录本身与inode一条关系,dir里包含了.和…(文件名)也与inode也有一条关系 = 2

acm
Access 最后访问时间
Modify 文件内容最后修改时间
Change 属性最后修改时间

 
 

2. 动态库和静态库

为使用别人的库做准备

2.1 静态库.a

2.1.1 如果想写一个库?(编写库的人的角度)

库里面要不要main函数呢?不要!
mkdir mklib
Makefile

libhello.a: mymath.o myprint.o
ar -rc libhello.a mymath.o myprint.o
mymath.o:mymath.c
gcc -c mymath.c -o mymath.o
myprint.o:myprint.c
gcc -c myprint.c -o myprint.o.PHONY:hello
hello:
mkdir -p hello/lib
mkdir -p hello/include
cp -rf *.h hello/include
cp -rf *.a hello/lib.PHONY:clean
clean:
rm -rf *.o libhello.a hello

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

mymath.c

#include "mymath.h"int addToTarget(int from, int to)
{int sum = 0;for(int i = from; i <= to; i++){sum += i;}return sum;
}

mymath.h

#pragma once#include<stdio.h>extern int addToTarget(int from, int to);myprint.c
#include "myprint.h"void Print(const char *str)
{printf("%s[%d]\n", str, (int)time(NULL));
}

myprint.h

#pragma once#include <stdio.h>
#include <time.h>extern void Print(const char *str);mkdir uselib
main.c
#include "myprint.h"
#include "mymath.h"int main()
{Print("hello world");int res = addToTarget(1,100);printf("res: %d\n", res);return 0;
}

main函数也在这个文件夹里
gcc main.c mymath.c myprint.c -o my.exe
./my.exe
hello world

main函数在另一个文件夹里
gcc -c mymath.c -o mymath.o
gcc -c myprintf.c -o myprintf.o
main.o
三个.o一链接就可以形成可执行程序了
gcc main.o mymath.o myprintf.o -o my.exe

如果我只把.h 和.o给别人用,可以吗?可以
.o文件太多了,麻烦。
可以把所有.o打包——这个过程就叫形成静态库
库的前缀必须是lib,后缀必须是.a,文件名可以随便取
ar 归档工具
ar -rc libhello.a mymath.o myprintf.o

 

2.1.2如果我把库给别人,别人怎么用呢?(使用库的人的角度)

头文件gcc的默认搜索路径是:/usr/include
库文件的默认搜索路径是:/lib64 或者 /usr/lib64

1.sudo cp hello/include/* /usr/inlcude/ -rf
2.sudo cp -rf hello/lib/libhello.a /lib64
会形成一个hello目录

gcc main.c 报错
自己写的库属于第三方库 (安装静态库
gcc main.c -hello
才会编译通过

我们刚刚拷贝到系统的默认路径下,就叫做库的安装
记得删掉,不要随便安装到系统路径

3.硬使用这个库
gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello
-I:头文件搜索路径
-L:库文件搜索路径
-lhello:指定在特定路径下,使用的库

静态库被使用时是拷贝进可执行程序内部

 

2.2 动态库.so

2.2.1站在制作库工程师的角度——动态库

静态库——地址确定(绝对地址)
动态库——地址不确定
一静一动

gcc -fPIC -c mymath.c -o mymath.o
gcc -fPIC -c myprintf.c -o myprintf.o
-fPIC形成一个与位置无关的二进制文件

将所有.o打包形成动态库
gcc -shared myprintf.o mymath.o -o libhello.so

一次形成两个库:
Makefile

.PHONY:all
all:libhello.so libhello.alibhello.so:mymath_d.o myprint_d.ogcc -shared mymath_d.o myprint_d.o -o libhello.so
mymath_d.o:mymath.cgcc -c -fPIC mymath.c -o mymath_d.o
myprint_d.o:myprint.cgcc -c -fPIC myprint.c -o myprint_d.olibhello.a: mymath.o myprint.o
ar -rc libhello.a mymath.o myprint.o
mymath.o:mymath.c
gcc -c mymath.c -o mymath.o
myprint.o:myprint.c
gcc -c myprint.c -o myprint.o.PHONY:output
output:
mkdir -p output/lib
mkdir -p output/include
cp -rf *.h output/include
cp -rf *.a output/libcp -rf *.so output/lib.PHONY:clean
clean:
rm -rf *.o *.a *.so output

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

make output 发布

mv uselib
打包
在这里插入图片描述

2.2.2 站在一个使用者(程序员)角度——使用动态库

链接:
前大i 后小L
gcc main.c -I output/include -L output/lib -lhello
gcc默认用的是动态库!
但是如果只有静态库,链接的时候就只能以静态方式链接

想要在有动态库的前提下,使用静态库:
gcc main.c -I output/include -L output/lib -lhello -static
-static的意义:摒弃默认优先使用动态库的原则,直接使用静态库

为什么使用动态库时可执行程序已经形成,但是一运行就报错?./a.out
程序是可执行的二进制程序
动态库是一个独立的库文件
动态库可以和可执行程序分批加载(静态库是同时加载)
(可以跳转到共享区)加载完可执行程序但是找不到动态库
之前所说的动态库的路径,是给gcc说的
运行加载的时候和gcc没有关系,需要再次像OS说明动态库路径

1.LD_LIBRARY_PATH
1:14:00
倒环境变量:

再次运行./a.out ldd a.out
就找到了
缺点:关闭终端之后,第二次登录之后,路径又不见了

2.修改配置文件
永久解决方案

sudo ldconfig更新

3.更简单的一种做法(但是不太推荐)
软链接方案

为什么要有库?

站在使用库的角度,库的存在,可以大大减少我们开发的周期,提高软件本身的质量。
站在写库的人的角度:简单,代码安全(逆向)

推荐两个好玩的库:
ncurses
boost

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

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

相关文章

中医-通过舌象判断身体状况

本文分享通过舌象判断身体的整体状况&#xff08;中医角度&#xff09;&#xff0c;得出一个可供辨证的参考&#xff0c;并且可以根据舌象做出相关的饮食调整&#xff0c;本文主讲理论&#xff0c;相关舌象图片易引人不适&#xff0c;如需找相关图片&#xff0c;可根据本文中的…

git rebase实战

例如&#xff0c; 在B分支上做rebase。 git rebase 之前确保当前分支是最新的。 切换到B分支&#xff1a; 1.git rebase origin/master(以origin/master分支为基线&#xff0c;合入master分支的修改到origin/master)此时会提示冲突文件 2.对冲突文件进行修改 3.git add 4.git …

网络面试-ox07http中的keep-alive以及长/短连接

非Keep-Alive: 早起HTTP1.0, 浏览器发起http请求需要与服务器建立新的TCP连接&#xff0c;请求处理后连接立即关闭。 缺点&#xff1a;每个这样的连接&#xff0c;客户端与服务器都要分配TCP的缓冲区和变量&#xff0c;这给服务器带来严重的负担。 Keep-Alive: 默认持久连接&am…

上海亚商投顾:沪指录得6连阳 两市成交再度破万亿

上海亚商投顾前言&#xff1a;无惧大盘大跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 三大指数今日横盘震荡&#xff0c;收盘集体小幅上扬&#xff0c;日K线均录得6连阳。虚拟现实概念股集体拉升&#…

最详细、最全面的【Java日志框架】介绍,建议收藏,包含JUL、log4j、logback、log4j2等所有主流框架

前言 本文为 【Java日志框架】 相关知识&#xff0c;之前已经介绍了Java日志框架的发展历史&#xff1a;Java日志框架的发展历史。 这篇文章将对日志的概念与作用&#xff0c;JUL日志框架&#xff0c;Log4j日志框架&#xff0c;Logback日志框架&#xff0c;Log4j2日志框架&…

详谈一下:Java中的基本类型变量(8种)与引用类型变量的区别

对于Java语言中的基本类型&#xff0c;不知道各位老铁是否还能全能说出来&#xff01;&#xff01; Java语言中的8种基本类型&#xff1a; byteshortintlongfloatdoublecharbollen 上面8种Java语言中的基本类型&#xff0c;所对应的变量&#xff0c;就是基本类型变量&#xf…

【代码随想录】二刷-字符串

字符串 代码随想录如果想让这套题目有意义&#xff0c;就不要申请额外空间。 344.反转字符串 双指针 // 时间复杂度O(n),执行n/2次交换 // 空间复杂度O(1) class Solution { public:void reverseString(vector<char>& s) {int n s.size();for(int left 0,right n-…

浅谈CAD如何精准导入图新地球并应用在工程行业

摘要&#xff1a;本文以重庆九建某某高校施工项目前期准备和施工验证工作为依托&#xff0c;以图新地球精准导入CAD为研究对象&#xff0c;总结了一套相对成熟且完善的应用技术。该应用技术能在实际地形和现状数据中迅速找到施工点的大致位置&#xff0c;为前期工程勘测争取足够…

22下半年软考集成广东卷(中项)真题在线估分

22年下半年广东软考也已经落下帷幕了&#xff0c;整理的2022年下半年软考集成广东卷答案已经出炉&#xff01; 在线估分预测一下分数~ 大家锦鲤附身&#xff01;都能过&#xff01; 第5题 ”十四五"规划和2035远景目标纲要就打造&#xff08; &#xff09;新优势、加快&a…

5. 凸集和凸函数

凸集和凸函数1.仿射集2.凸集3.向量范数4.凸集的性质5.凸函数6.凸函数的一阶二阶条件7. 保凸运算8.凸函数和凸集的关系1.仿射集 2.凸集 仿射集 -------> 凸集 凸集 ----//----> 仿射集 3.向量范数 4.凸集的性质 5.凸函数 6.凸函数的一阶二阶条件 7. 保凸运算 凸函数的性…

海外拼多多Temu最新动态,怎么快速提升销量和权重?(测评补单)

上线一个多月后&#xff0c;拼多多跨境业务Temu的日均GMV突破了150万美元&#xff0c;入驻商家数量近3万个&#xff0c;SKU在30-40万&#xff0c;涵盖了24个一级类目。 据报道&#xff0c;目前Temu的日活成交用户在6万左右&#xff0c;下载用户接近80万&#xff0c;30天的复购…

vue3与vue2的不同内容

一、main.js入口文件的不同 // 引入的不再是构造函数&#xff0c;引入了一个名为creacteApp的工厂函数 import { createApp } from vue import ./style.css import App from ./App.vue // 创建应用示例对象--->app const app createApp(App) //把组件APP挂载到#app节点上 …

(最新版2022版)剑指offer之动态规划题解

&#xff08;最新版2022版&#xff09;剑指offer之动态规划题解[剑指 Offer 42. 连续子数组的最大和][剑指 Offer 47. 礼物的最大价值][剑指 Offer 46. 把数字翻译成字符串][剑指 Offer 48. 最长不含重复字符的子字符][剑指 Offer 48. 矩形覆盖][剑指 Offer 买卖股票的最好时机…

SpringSecurity Oauth2实战 - 06 拦截器获取用户登录信息并存储到本地线程ThreadLocal

文章目录1. 获取用户登录信息1. 用户信息共享的ThreadLocal类 UserInfoShareHolder2. 写一个拦截器 UserInfoInterceptor3. 配置拦截器 CommonWebMvcAutoConfiguration2. 源码分析1. 认证用户通过access_token访问受限资源2. 进入过滤器 OAuth2AuthenticationProcessingFilter#…

自动驾驶技术综述2:自动驾驶决策规划模块算法介绍

一、前言&#xff1a; 在自动驾驶整个软件框架中&#xff0c;决策规划模块有着重要的作用。决策规划模块一般也叫Planning模块&#xff0c;在整个自动驾驶系统中&#xff0c;Planning模块相当于人类驾驶员的大脑&#xff0c;它的上游是地图、导航、感知、预测这些模块&#xf…

Android Studio App开发中数据库SQLite的解析及实战使用(包括创建数据库,增删改查,记住密码等 附源码必看)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~ SQLite简介 SQLite是一种小巧的嵌入式数据库&#xff0c;使用方便&#xff0c;开发简单&#xff0c;如同mysql&#xff0c;oracle那样&#xff0c;SQLite也采用SQL语句管理数据&#xff0c;由于它属于轻型数据库&#xff0…

Github已经54k个star的Docker,到底是什么?

做开发的应该很多人都知道Docker&#xff0c;就算是没有用过&#xff0c;应该也有所耳闻。这款开源于2013年的工具一经问世&#xff0c;便迅速火爆起来&#xff0c;在微服务、项目迁移、云等方面备受欢迎。如今它的github项目已经达到54k个star。Docker到底是什么&#xff1f;它…

零基础入门网络安全,收藏这篇不迷茫【2022最新】

前言 最近收到不少关注朋友的私信和留言&#xff0c;大多数都是零基础小友入门网络安全。其实看过的铁粉都知道&#xff0c;之前的文里是有过推荐过的。新来的小友可能不太清楚&#xff0c;这里就系统地叙述一遍。 01.简单了解一下网络安全 说白了&#xff0c;网络安全就是指…

Golang源码分析:golang/sync之singleflight

文章目录1.背景1.1. 项目介绍1.2.使用方法2.源码分析2.1.项目结构2.2.数据结构2.3.API代码流程3.总结1.背景 1.1. 项目介绍 golang/sync库拓展了官方自带的sync库&#xff0c;提供了errgroup、semaphore、singleflight及syncmap四个包&#xff0c;本次分析singlefliht的源代码…

mysql用户管理和用户授权

目录 一、mysql用户管理 1 新建用户 1&#xff1a;使用明文密码创建用户 2&#xff1a;使用密文密码创建用户 2 查看用户信息 3 重命名用户 rename 4 删除用户信息 drop 5 修改当前登录用户的密码 6 修改其他用户的密码 7 忘记root用户密码的解决办法 8 查看当前登录用户 二、…