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

Linux文件系统概述

文件系统概述

本文已收录至《Linux知识与编程》专栏!
作者:ARMCSKGT
演示环境:CentOS 7

在这里插入图片描述


文件系统概述

  • 前言
  • 正文
    • 文件与磁盘
    • 磁盘介绍与机械硬盘
      • 机械硬盘基础结构
      • 机械硬盘数据存储与管理
    • 文件操作的细节
  • 最后


前言

我们知道文件的存储一般在磁盘上,操作系统需要管理这些文件就需要通过其文件系统进行管理,高效的管理机制有利于提高我们IO的速度,本节我们将对Linux系统的文件系统进行概述!
文件系统


正文

本节理论较多,还请耐心阅读和理解!

文件与磁盘


文件被打开后会加载到内存,而没有被打开的文件存储在磁盘上!
对于磁盘文件的管理,主要为了解决快速定位,快速读取和写入

对于在磁盘上的文件,当我们对文件进行操作时,操作系统会通过文件的inode编号找到文件属性进行文件操作,对于文件的inode编号我们可以通过以下命令查看:

ls -il

inode编号查看命令
文件的inode编号就如同进程的pid一样,inode编号与文件一 一对应,通过文件的inode编号就可以访问文件属性进而读取文件内容!

我们可以将磁盘对文件的管理比喻为物品寄存点,每一个柜子有一个箱号,可以存放一个物品,存放成功后物主获得箱号牌;待物主来取时通过箱号牌取出物品并归还箱号牌;这就是文件的一次写入和删除操作!

向磁盘中写入一个文件,存放在磁盘中,获取一个inode编号,在删除这个文件时归还这个inode编号即可!
物品寄存处
以上对文件的 “管理” 描述只是抽象概念,结合我们后面介绍的磁盘结构,才能更好的理解!


磁盘介绍与机械硬盘


在现代,磁盘分为两种,即机械硬盘固态硬盘
机械硬盘速度慢,但是便宜稳定;固态硬盘速度快,但是价格比较贵且数据损坏率大于机械硬盘!
为了更好的介绍文件系统,我们主要围绕机械硬盘进行讲解!
机械硬盘和固态硬盘


机械硬盘基础结构

机械硬盘是我们计算机中的一个外部设备,也是计算机中唯一的机械设备,根据冯诺依曼体系,机械硬盘的速度远远低于CPU。如果要有一个数据去衡量,CPU的运行是纳秒级别的话,机械硬盘则是毫秒级别!

而机械硬盘之所以这么慢,是由其内部结构决定的:
机械硬盘结构

机械硬盘的主要结构:

  • 盘片:有两面都可以存储数据,一般是多个盘片组合成一组
  • 磁头:盘片的每一面都配有一个磁头读写数据
  • 主轴:带动盘片转动进行寻址
  • 音圈马达:控制磁头进退换道
  • 磁头臂:磁头在磁头臂的一端,通过音圈马达的摆动,控制磁头切换磁道
  • 伺服电路板:对数据的读写进行处理,控制机械硬盘的运行
  • 其他 … …
注意:不同磁盘中磁盘的盘片数量不一样,但因为磁头是通过一个磁头臂驱动的,所以一个机械硬盘上的所有磁头是共进退的!机械设备的操作动作需要时间,相当于固态硬盘中电子间的光速传输来说,非常慢!

磁头摆动
关于机械硬盘的详细结构介绍,可阅读:机械硬盘的内部结构


机械硬盘数据存储与管理

在计算机中,数据是以二进制存储的,常见的可以表示二进制的存储方式有:高电平与低电平,波峰和波谷,南极和北极等等;而机械硬盘盘片的存储的方式是磁极南极和北极!
磁头写入
磁头写入
读写数据时,距离盘面3纳米的磁头会利用电磁铁,改变磁盘上磁性材料的极性来记录和删除数据,两种极性分别对应 0 或 1 ,磁头移动到指定扇区位置,向扇区写入数据时磁极由N->S,在扇区删除数据时磁极由S->N (S为1 N为0)

磁头和盘片的近距离操作,使得机械硬盘在运行时我们不能随意移动,更不能发生碰撞,一旦因为外力使磁头接触到盘片损伤了盘片就会导致数据丢失!


关于机械硬盘的工作原理详细讲解:




对于一个盘片,有两个盘面,每个盘面上又分为很多个磁道,每个磁道又分为很多个扇区!
盘面
单个扇区大小为 512 字节(或者 4 kb),这些扇区用来存储数据,同一半径中的所有扇区组成一个扇面;而半径相同的扇区组成磁道(柱面)!
注意:磁道上扇区的数量一般相同,因为磁道的面积会随着向外越来越打,对于面积较小的磁道,其扇区比特位会做的相对紧密一些,面积较大的扇区则会做的稀疏一些!

未来要找一个扇区:

  • 先找磁头(head):定位在哪一个盘片以及哪一个面,只需要确定哪一个磁头(磁头编号)就能找到哪一个面
  • 再找柱面(cylinder):定位在哪一个磁道,由半径决定,柱面也就是磁道
  • 最后找扇区(sector):定位读取位置在该磁道的哪一个扇区,根据扇区的编号定位一个扇区


    我们称这种:先定位磁头,再定位柱面(磁道),再定位扇区的方式,称为CHS定位法

磁盘扇区
一个普通文件的属性和数据都是数据(0/1),无非就是占用一个或多个扇区来进行自己的数据存储的;我们既然能够用CHS定位任意一个扇区,我们就能定位任意多个扇区,从而将文件从硬件角度进行读写!

通过上述,如果操作系统能够得知任意一个CHS地址,就能访问任意一个扇区;但操作系统并非直接使用CHS地址,因为操作系统是软件,磁盘是硬件,硬件是一个地址,如果操作系统直接使用这个地址,如果硬件参数发生了变化,操作系统的磁盘信息也要变化,操作系统要和硬件做好解耦工作,即便是扇区,512字节单IO的基本数据量也是很小的,硬件是按照512字节处理,但操作系统实际进行IO的基本单位是4KB进行处理!

所以,操作系统的一次IO,无论读取数据是多少,都是按照4KB进行读取,因此磁盘也称块设备


我们将磁盘中一个盘面的所有磁道想象成磁带被全部拉出来的样子,那么就是一直连续的线性结构!
磁带
操作系统需要有一套通用的新地址来进行块级别的访问,如果将磁道比方成磁带,那么一个磁道就可以当成一个数组对待,数组天然有下标,此时定位一个扇区,只需要一个数组下标就可以定位一个扇区,假设数组下标为N,而其中我们的操作系统是以4KB为单位进行IO的,故一个操作系统级别的文件块要包括8个扇区,甚至在OS角度,OS不关心扇区!

计算机常规的访问方式是起始地址+偏移量的方式(语言/数据类型);操作系统只需要知道数据所在的起始地址(第一个扇区的下标地址)+4kb(块的类型)就能找到一个数据,我们把数据块看做一种类型!

所以块的地址本质就是数组的一个下标N,以后我们表示一个块,我们可以采用先选下标N的方式定位任意一个块了,我们称这种线性地址为逻辑块地址LBA,这样我们定位磁盘扇区就转换为OS->N->LBA逻辑块地址->CHS;磁盘只认CHS地址,所以LBA地址和CHS地址要相互转换!


操作系统要管磁盘,就将磁盘看做一个大数组,对磁盘的管理,变成了对数组的管理,要对一个数组中的扇区进行管理,就需要先描述再组织,通过struct对象封装8个扇区,存储中数组中,在数组中每一个下标对应的就是一个数据块


在操作系统中有描述一个块的的结构体struct block{}


硬盘比较大,为了合理的管理一般操作系统可以分区,对于每个分区操作系统又会分组,这个组就是块组!块细分
对于分区,就相对复杂一些!
我们在电脑中一般会对电脑进行分区,分区的意义在于,磁盘的空间是非常大的,如果不分区,巨大的空间管理会消耗操作系统的资源,我们在现实生活中,各大学都会在学校设立不同的学院进行高效管理,最重要的是上层管理者更好的调用管理资源,这种思想称为分治思想

在文件系统中,操作系统先将整个大文件系统分为不同的区,存入struct disk数组中进行管理

//分区属性
struct disk
{struct part[3]; //三个分区    struct part是管理分区的对象类型//其他属性...	
}

我们可以通过以下命令查看当前Linux系统的分区:

ll /dev/vda* -i 

分区情况
也可以通过下面的命令查看分区的信息:

# 该命令相当于Windows的 “此电脑”
df -h

分区信息
系统在分区后,需要对区块进行格式化,在格式化时写入管理信息,不同的文件系统在格式化时写入的数据是不同的,这里讨论的是EXT文件系统!

对于分区

  • 为了使分区能被正常使用,需要对分区进行格式化
  • 分区格式化:操作系统向分区写入文件系统的管理属性信息
  • 磁盘分区后,分组、填写系统属性是操作系统做的事

当然,分区再细分就是块组!
分区
块组构成的线性空间亦可称为组线,代表一个分区,而一个struct part对象管理一个分区:

struct part
{struct part group[512];	//分为512个块组int lba_start;	//起始块组位置(分区中第一个块组的下标)int lba_end;		//结束块组位置(最后一个块组下标)//其他属性……
}

将现有资源再分配后,可以 最大化利用资源,避免造成浪费及拖慢效率,下面我们详细介绍块组!

块组是由分区细分出的产物,块组与分区的关系如图所示:
分区分组
关于这些分组信息的详细介绍:
分组信息
我们知道 文件 = 内容+属性 ,而Linux系统将文件属性和内容分离存储!

用户只认文件名,Linux系统只认inode号,文件的inode属性中,并不存在文件名,文件名是给用户用的,所以目录也是文件,目录也有inode,而目录存储的是文件名与inode的映射关系

inode可以确定分组,inode编号在一个分区内唯一有效,不能跨分区,但一个inode是可以在整个分区有效的,所以每一个分区的inode编号有一个范围(因为分组中的inode都有一个范围),分组也是!

当然,对于一些大文件,Linux系统不一定会直接分配块进行存储,而是进行块索引多级存储!
索引映射存储


文件操作的细节


创建文件

简单直接的说,就是实例化一个inode对象,就相当于创建了一个文件,但是有一些细节!

当我们增加一个文件时,操作系统需要:

  • 首先操作系统在该目录所在分组中的inode Bitmap找到一个没有被使用的inode,在inode table中找到这个inode拿到文件属性和inode编号
  • 将文件默认属性写入inode中,一开始文件是空的所以没有数据块
  • 在对应目录的存储内容中追加一条文件名与inode的映射关系,然后文件就创建好了

未来对文件进行写入时,先去block Bitmap找到需要的数据块将这些块的bit位置为1,然后将这些数据块的位图信息填入文件inode的blocks数组中,再去data block中找到对应的数据块进行写入(刷新入)即可;同样的,当我们删除了某些数据,减小了数据块的占用时,将该文件不用的数据块在block Bitmap中置为0即可,表示可分配!


访问文件

当我们要访问一个文件时,操作系统需要:

  • 首先我们会在特定目录下找到文件名(就相当于找到了inode编号)
  • 一个目录也是一个文件,也一定隶属于一个分区,结合inode,在该分区中找到分组,在该分组的inode table中找到文件的inode属性
  • 通过inode(的blocks数组)和data block的映射关系,找到该文件的数据块,并加载到内存中(被操作系统管理),并进行访问和操作

删除文件

当我们要删除文件时,操作系统需要:

  • 先通过当前目录下文件名找到对应的inode编号
  • 根据inode table找到文件的inode属性,然后将inode属性中blocks数组所占数据块对应的block Bitmap的bit位置为0
  • 将inode Bitmap中文件inode位置的比特位设置为0,然后文件属性就没了,文件也就不存在了,被删除了

所以删文件只需要修改位图即可,从这里可以看出,操作系统的删除只是改变标识,并没有销毁数据内容,如果要彻底销毁,则需要借助一点手段!


恢复文件

文件被误删不一定没救,有可能可以恢复!
在数据被误删后,此时一定不要再动电脑,立刻断电送修,还可能挽回数据!

前面说过,删除并不是真删除,访问不到就行了,所以只要在删除后,有些操作系统会记录日志,日志中会保存被删的inode编号!

所以,理论上可以:

  • 根据日志找到被删文件的inode编号
  • 根据inode编号找到对应的inode,将分组中的该inode的inode Bitmap表其位置置为1
  • 找到其所占用的Data block,将其占用的data block在block Bitmap置为1

其中的内容没有被覆盖的,数据就可以找回来
所以,当我们误删文件后,不进行操作就可以防止被释放的数据块中的内容被覆盖!
当然,如果我们不想这么麻烦,也可以学习Windows创建一个回收站!


其他情况

如果inode只是单单的用数组建立和datablock的映射关系,即只是将inode对象实例化不同的文件系统datablock数组大小不同存在组中inode用完了但datablock没用完的情况,也存在inode没用完但是datablock用完了的情况!

也就是说,存在两种情况

  • 如果我们一直只创建文件,但不写入内容,那么就会导致一个分组中indoe table被全部占满,此时就会导致datablock数据块没有占用,但分组已经无法再容纳新文件了
  • 如果我们创建几个文件,但是文件内容非常大,用完了这个分组的所有datablock数据块,此时就会导致很多inode没有使用,但分组空间已满的情况

最后

文件系统概述到这里就基本结束了,本节我们带领大家简单的探究了Ext文件系统对于文件的管理方式,从硬件“机械硬盘”入手,再到文件系统的管理,两者的结合,一气呵成,相信大家了解了文件系统之后,才会发现操作系统对于文件的管理是多么高效和巧妙!

本次 <Linux文件系统概述> 就先介绍到这里啦,希望能够尽可能帮助到大家。

如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!
结尾

🌟其他文章阅读推荐🌟
Linux<重定向和缓冲区理解> -CSDN博客
Linux<文件理解和系统调用> -CSDN博客
Linux<进程控制> -CSDN博客
Linux<进程地址空间> -CSDN博客
Linux<环境变量> -CSDN博客
🌹欢迎读者多多浏览多多支持!🌹

相关文章:

Linux文件系统概述

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 文件系统概述 前言正文文件与磁盘磁盘介绍与机械硬盘机械硬盘基础结构机械硬盘数据存储与管理 文件操作的细节创建文件访问文件删除文件恢复文件其他情况 最后 前言 …...

go专业数据结构与算法

go语言之专业数据结构与算法 2.数组概念 3.golang实现数组结构 4.golang实现数组迭代器 5.数组栈的高级实现 6.栈模拟低级递归 7.斐波那契数列栈模拟递归 8.递归实现文件夹遍历 9.栈模拟文件递归 10.层级展示文件夹 11.数组队列的实现 12.队列实现遍历文件夹 13.循环队列 14.链…...

Hive on Spark的小文件设置参数

Hive on Spark的小文件设置参数 参数调优 了解完了Spark作业运行的基本原理之后&#xff0c;对资源相关的参数就容易理解了。所谓的Spark资源参数调优&#xff0c;其实主要就是对Spark运行过程中各个使用资源的地方&#xff0c;通过调节各种参数&#xff0c;来优化资源使用的效…...

高级SQL语句

目录 MySQL 高级(进阶) SQL 语句函数数学函数&#xff1a;聚合函数字符串函数&#xff1a; 连接查询inner join(内连接)&#xff1a;left join(左连接)&#xff1a;right join(右连接)&#xff1a; CREATE VIEW&#xff08;视图&#xff09;UNION&#xff08;联集&#xff09;C…...

IDE /skipping incompatible xxx_d.dll when searching for -lxxx_d

文章目录 概述场景复现用以测试的代码编译器位数不匹配导致?保持编译器类型一致再验证编译器位数的影响MingW下调用OS的库咋不告警?以mingW下使用winSocket为例MingW下网络编程的头文件分析该环境下链接的ws2_32库文件在哪里&#xff1f;mingW为啥可以兼容window下的动态库 概…...

C语言学习准备-编辑器选择

今天继续给大家更新C语言经典案例 今天的案例会比昨天稍微有一些难度&#xff0c;但是同时还是非常经典的案例 本来是想给大家继续更新C语言经典案例&#xff0c;但是有朋友反应C语言编辑器的选择&#xff0c;刚好我自己也是想更换一下C语言的编辑器&#xff0c;跟大家分享一下…...

微信为什么使用 SQLite 保存聊天记录?

概要 SQLite 是一个被大家低估的数据库&#xff0c;但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上&#xff0c;SQLite 是一个非常可靠的数据库&#xff0c;它可以处理 TB 级的数据&#xff0c;但它没有网络层。接下来&#xff0c;本文将与大家共同探讨 SQLite 在…...

VB串口通讯方式解释

目前,Visual Basic (简称VB) 已成为WINDOWS 系统开发的主要语言,以其高效、简单易学及功能强大的特点越来越为广大程序设计人员及用户所青睐。VB 支持面向对象的程序设计,具有结构化的事件驱动编程模式并可以使用无限扩增的控件。在VB 应用程序中可以方便地调用WINDOWS API函数…...

Mybatis-Plus不能更新对象字段为空值问题解决

问题描述&#xff1a; 在使用Mybatis-Plus调用updateById方法进行数据更新默认情况下是不能更新空值字段的&#xff0c;而在实际开发过程中&#xff0c;往往会遇到需要将字段值更新为空值的情况&#xff0c;该如何解决呢&#xff1f; 原因分析&#xff1a; Mybatis-Plus中字…...

d3dx9_43.dll丢失怎么解决

d3dx9_43.dll丢失的影响 当我们在运行某些需要DirectX 9支持的程序时&#xff0c;如果系统中缺少d3dx9_43.dll文件&#xff0c;就会出现错误提示&#xff0c;导致程序无法正常启动。这个错误提示通常会类似于“找不到d3dx9_43.dll”或“d3dx9_43.dll不存在”。 打开电脑浏览器…...

【花雕】全国青少年机器人技术一级考试备考实操搭建手册8

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…...

【UE5 Cesium】09-Cesium for Unreal 子关卡应用实例(下)

效果 通过按钮点击事件实现子关卡的切换 步骤 新建两个Actor蓝图作为GeoMarker&#xff0c;分别命名为“BP_GeoMarker_BeiJing”、“BP_GeoMarker_ShangHai” 分别打开这两个蓝图&#xff0c;添加文本渲染组件 在指定的地理位置上拖入蓝图“BP_GeoMarker_BeiJing” 控制“BP_…...

插值应用案例2

案例1 高点和高程 在一丘陵地带测量高程&#xff0c;x和y方向每隔100m测一个点&#xff0c;得到高程如下表所列&#xff0c;试插值一曲面&#xff0c;确定合适的模型&#xff0c;并由此测到最高点和相应的高程。 x0/z0\y0 100 200 300 400 500 100 636 697 624 478 …...

【新星计划Linux】——常用命令(1)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 一.常用命令 1.Linux的基本原则&#xff1a; 用户接口&#xff1a; 2.命令形…...

python应用-excel和数据库的读取及写入操作

近日完成一个交办任务&#xff0c;从excel表读取数据&#xff0c;根据ID在数据库表匹配相应的记录&#xff0c;并回填至excel表里。我使用的工具是python。下面记录下相应的模块。 一、从excel表读取数据 import pandas as pd import numpy as npdef read_excel():path &quo…...

MySQL Optimization Learning(一)

目录 一、MySQL性能监控 1、show profile 2、performance schema 2.1、MYSQL performance schema详解 3、show processlist 一、MySQL性能监控 MySQL官网 拖到首页最下方找到 MySQL Reference Manual ->cmd命令行 C:\Users\Administrator>mysql -uroot -proot …...

Flink消费kafka出现空指针异常

文章目录 出现场景&#xff1a;表现&#xff1a;问题&#xff1a;解决&#xff1a; tombstone : Kafka中提供了一个墓碑消息&#xff08;tombstone&#xff09;的概念&#xff0c;如果一条消息的key不为null&#xff0c;但是其value为null&#xff0c;那么此消息就是墓碑消息. …...

【探索 Kubernetes|作业管理篇 系列 9】Pod 的服务对象

前言 大家好&#xff0c;我是秋意零。 在上一篇中&#xff0c;我们介绍了 Pod 的生命周期以及区分 Pod 字段的层次级别&#xff0c;相信你对此有了充分的认识。 今天&#xff0c;我们还会接着以 Pod 展开&#xff0c;说说它的 “服务对象”&#xff0c;一听就知道是对 Pod 提…...

多种拖拽= =自用留档

<template> <div class"main-drag"> <div v-if"stencil 0" class"mapped-fields"> <el-form ref"mapped" :model"mapped" class"demo-fieldsForm"> <el-form-item label"切换数…...

贝叶斯与认知——读《贝叶斯的博弈》有感

关于对贝叶斯与认知问题的相关思考 一、贝叶斯定理二、贝叶斯与认知的本质三、经验的偏见四、总结 自古以来&#xff0c;人们就在思考知识来自何处&#xff0c;“冯翼惟象&#xff0c;何以识之&#xff1f;”&#xff0c;对此的思考逐渐发展成哲学的认识论分支。德国哲学家康德…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

【工具教程】多个条形码识别用条码内容对图片重命名,批量PDF条形码识别后用条码内容批量改名,使用教程及注意事项

一、条形码识别改名使用教程 打开软件并选择处理模式&#xff1a;打开软件后&#xff0c;根据要处理的文件类型&#xff0c;选择 “图片识别模式” 或 “PDF 识别模式”。如果是处理包含条形码的 PDF 文件&#xff0c;就选择 “PDF 识别模式”&#xff1b;若是处理图片文件&…...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟

众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了&#xff0c;延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp &#xff0c;边缘服务器拉流推送到云服务器 …...