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

文件【Linux操作系统】

文章目录

  • 文件
    • 前置知识
      • 访问文件之前,为什么文件必须打开?
      • 文件的管理
    • 标准流
      • 标准错误流的作用是什么?
    • 进程和文件的关系
      • 在用户层面文件描述符是访问文件的唯一方式,因为系统调用接口只能通过文件描述符来找到对应的文件
    • 操作文件的系统调用
      • 系统调用函数:open
      • 系统调用函数:umask
      • 系统调用函数:close
      • 系统调用:unlink
      • 系统调用函数:fsync
      • 系统调用函数:read
      • 系统调用函数:write
    • 如何理解Linux下一切皆文件
      • 以硬件为例:
    • IO的基本过程
      • 写入
      • 读取
      • 修改
      • 为什么要有这个文件内核缓冲区?

文件

前置知识

在磁盘中的文件:
文件=内容+属性

访问文件之前,为什么文件必须打开?

  1. 文件什么时候才会被打开?
    文件只有在代码编译形成可执行程序,可执行程序加载到内存变成进程,运行到打开文件的函数时文件才会被打开

  2. 访问文件的是谁?
    是进程
    是进程打开文件,再使用函数封装的系统调用对文件进行访问的

  3. 文件在打开之前,在磁盘中
    进程运行的本质是:CPU执行进程的代码,访问进程的数据
    进程对文件读取/写入时,本质是数据流转(拷贝),所以这个操作也是由CPU执行
    但是根据冯诺依曼体系结构,CPU是不能直接访问磁盘的,因为这样太慢了
    所以文件必须加载到内存之后,才能直接访问
    所以打开文件的本质是把文件加载到内存


文件的管理

一个进程可以打开多个文件,而被加载到内存的进程需要被管理
那被加载到内存的比进程个数更多的文件也一定会被操作系统管理起来

所以在内存中的文件:
文件=文件的内核数据结构+文件里面的内容
而磁盘中的文件也=内容+属性
所以:
内存中的文件的内容就是磁盘中文件的内容
内核数据结构中存储了文件的属性



标准流

一个进程在启动时,会默认打开3个流:
①标准输入,底层对应键盘
②标准输出,底层对应显示器
③标准错误,底层对应显示器

因为Linux下一切皆文件,键盘和显示器也被包装成了文件
所以我们可以使用文件指针(FILE*)的方式访问它们
在这里插入图片描述


标准错误流的作用是什么?

标准输出和标准错误都是把信息打印到显示器,那为什么还要有标准错误呢?
直接用标准输出打印错误不就行了吗?

这是因为人们使用标准输出时,可以打印各种各样的信息

而人们使用标准错误时,一般只会打印某些代码出错时的错误信息
而且标准输出和标准错误虽然都是向显示器写入,但是标准输出和标准错误它们两个对应的是不同的文件,文件描述符也不同

可以根据这个特点,虽然它们两个打印的信息都是打印到显示器中,但是我们可以把它们打印到信息分离保存到不同文件中,这样在调试时就可以只看标准错误输出的错误信息

例如
重定向标准输出和标准错误,分别生成日志,这样就在出现错误的时候,就可以直接查看错误日志



进程和文件的关系

进程可以把数据给文件,文件也可以把内容给进程
进程可以修改文件的属性,文件的属性对进程也拥有限制

所以:
我们研究打开的文件,就是在研究进程与打开文件的关系

进程加载到内存之后,一定会打开至少3个文件(每个进程运行之后,都会打开标志输入,标准输出,标准错误3个文件

打开的文件会被加载到内存,因为打开的文件会有多个
所以操作系统一定会把打开的文件管理起来

也就是对打开的文件:先描述[struct file]再组织

即为打开的文件定义了一个结构体,里面存储打开文件的属性
[由操作系统定义的与读写有关等运行属性+磁盘中存储的文件的基本属性构成]

再使用合适的数据结构把所有的struct file装起来
这样对打开文件的管理,就变成了对数据结构的增删查改

操作系统中:
进程和文件是两个不同的模块,所以它们之间肯定不能强耦合
只能弱耦合:
每个进程只需要能找到自己打开的文件就行了,剩下的对文件的各种操作,都通过函数/系统调用接口完成

所以只需要在创建一个结构体变量,进程存储指向它的指针,用它来管理进程自己打开的文件

所以:

  1. 进程PCB中就存储了struct files_struct*类型的指针,指向一个自己对应的结构体变量
    这个结构体就是:struct files_struct

  2. struct files_struct里面创建了一个叫做文件描述符表的指针数组[struct file* fd_array[N]]

  3. 指针数组中存储了struct file*类型指针,数组下标就是文件描述符

所以进程使用系统调用read和write等系统调用时

  1. 就是进程通过在CPU上执行系统调用的代码找到该进程的PCB
  2. 再通过PCB里面的指针找到struct files_struct
  3. 再通过文件描述符进行数组访问,找到对应的文件对应的struct file
    在这里插入图片描述

所以进程管理和文件管理就通过struct files_struct和struct file* fd_array[N]进行弱耦合


在用户层面文件描述符是访问文件的唯一方式,因为系统调用接口只能通过文件描述符来找到对应的文件

因为文件在磁盘中,用户只能通过操作系统的系统调用来访问它
所以任何语言访问文件的方式都是对系统调用的封装(封装是为了更好地供用户使用)

所以它们都必定会封装文件描述符等拱系统调用使用的信息

所以语言对文件访问的封装体现在两个方面
①对文件操作的系统调用函数的封装
②对文件属性(信息)的封装,并且一定对文件描述符进行了封装

例:
FILE是C语言库提供的结构体,它封装了文件描述符等属性信息
fopen函数对open进行了封装

在这里插入图片描述



操作文件的系统调用

因为文件是存储在磁盘中的
所以任何语言想对文件进行操作,都必须通过操作系统的系统调用接口先访问到磁盘
进而访问文件,才能把文件读取到内存

所以任何语言的文件接口,底层都必须封装对应的文件类系统调用

系统调用函数:open

头文件:sys/types.hsys/stat.hfcntl.h
返回值:int类型
①成功,就返回文件描述符
②失败,就返回-1

参数表:(const char*p,int f,mode_t mode)
①p:带(或者不带)路径的文件名
②f:位图
宏标记位:
1,O_RDONLY:只读
2,O_WRONLY:只写
3,O_RDWR:读写
4,O_CREAT:没有对应文件时,创建文件
5,O_APPEND:追加
6,O_TRUNC:打开文件时,清空文件内容
可以通过按位或,一次传递多个标志位宏

③mode:文件的最初起始权限[即减umask之前的权限],以0+3个八进制位数字表示
权限使用分两种情况
1,要打开的文件已经存在,就可以不传

2,要打开的文件不存在,就要传,不然创建出来的文件的权限就是乱码

因为操作系统中创建文件和权限是两个不同的分支功能

操作系统对它们进行了解藕,所以不能在创建文件的同时给予它起始权限,只能先指定文件的起始权限,再创建文件



系统调用函数:umask

头文件:sys/types.hsys/stat.h
参数:mode_t mode
以0+3个八进制位数字表示

作用:将自己这个进程的权限掩码设置成传入的参数



系统调用函数:close

头文件:unistd.h

参数:int fd
即文件描述符

作用:关闭文件


系统调用:unlink

头文件:unistd.h
返回值:int类型
①成功返回0
②失败返回-1
参数表:
path:带路径的文件名

作用:删除一个指定路径的文件



系统调用函数:fsync

头文件:unistd.h

参数:int fd
即文件描述符

作用:刷新文件描述符为fd的文件的内核缓冲区



系统调用函数:read

头文件:unistd.h
返回值:size_t n
①n>0,表示读取到了多少个字节
②n=0,表示只读取到了文件结尾标志或者文件关闭了或者连接断开了
为什么不是文件内核缓冲区没有数据了呢?
因为read是阻塞式读取的
所以如果缓冲区没有数据read就阻塞了,根本不会返回

③n<0,读取出错或者read函数异常

参数表(int fd,void*buf,size_t count)
①fd:文件描述符
②buf:读取缓冲区
③count:期望读取到的字节总数

作用:读取文件内容



系统调用函数:write

头文件:unistd.h
返回值:size_t n
①n>0,表示写入了多少个字节
②n=0,表示文件关闭了或者连接断开了

为什么不是文件内核缓冲区满了呢?
因为write是阻塞式写入的
所以如果缓冲区满了,write再写就阻塞了,根本不会返回

③n<0,读取出错或者write函数异常

参数表(int fd,void*buf,size_t count)
①fd:文件描述符
②buf:写入缓冲区
③count:写入的字节总数

作用:用文本写入方式向文件写入

所以:
语言中的文件接口fopen,fclose,read等底层都会封装open,close,read等系统调用



如何理解Linux下一切皆文件

电脑的硬件也有很多,操作系统作为软硬件的管理者

以硬件为例:

电脑的硬件也有很多,操作系统作为软硬件的管理者
必然需要对所有硬件也进行管理

管理方案还是:先描述,再组织
也就是给所有硬件也设置一个结构体,通过驱动程序获取硬件信息,初始化出结构体变量,再把所有的结构体变量放进数据结构中

内存与外设之间最主要的操作就是IO(读写)操作【其他操作也一样,多搞几个函数指针的问题

所以所有的外设都得向操作系统(内存)提供读写方法

因为每个硬件的具体情况不同,它们实现读写的实现肯定是不同的(即函数的实现不同)
但是提供的接口都叫读(写)接口[read()write()]

所以操作系统只需要,在struct file中设置函数指针,分别指向read()和write()等接口
就可以通过函数指针使用所有的外设的读写函数[根据地址的不同,即可使用不同的外设定义的不同函数]
在这里插入图片描述

此时就能做到:
通过struct file对外设进行读写时
不需要管外设是谁,不管它读写函数的函数实现是什么,只需要知道要读什么,写什么

这不就是在struct file的上层把外设当成文件了吗?

操作系统的open,close,read等系统调用的实现就是
找到对应的struct file结构体变量,通过里面的函数指针调用对应外设根据自己的实际情况实现的函数


所以站着进程角度,Linux下一切皆文件
因为用户的一切操作(命令)都是由进程执行,所以用户也认为一切皆文件

这不就是使用C语言实现的多态吗!!!
在这里插入图片描述



IO的基本过程

写入

使用write进行写入时:

  1. 通过文件描述符找到对应的文件的struct file结构变量

  2. 找到文件的struct flie中的一个指针指向的内核缓冲区,再把要写入文件的内容拷贝进去

  3. 操作系统认为可以写入时[所以系统调用write的作用其实只有拷贝到内核缓冲区,没有写入到文件]
    再使用文件的structfile中对应的写接口的函数指针,把内核缓冲区中的数据写入到磁盘文件

操作系统认为要可以写入时,在windons中其实一般是用户编写文件过程中,点击了保存按钮
所以我们使用键盘向文件进行写入时,其实一直在使用write这样的系统调用把数据写到缓冲区中,点击保存时才是写入文件。

如果操作系统认为当前IO压力不大,操作系统觉得挺闲的也有可能内核缓冲区出现数据,它就刷新



读取

使用read进行读取时:

  1. 通过文件描述符找到对应的文件的struct file结构变量

  2. 找到文件的struct flie中的一个指针指向的内核缓冲区,再把要读取的数据拷贝到用户指定位置

  3. 如果内核缓冲区中还没有要读取的数据,就会尝试使用struct flie指向的函数指针集合中的读取的函数指针调用读函数
    把数据先从外设读取到内核缓冲区,再拷贝到用户指定位置
    这种情况就有可能导致进程阻塞,最常见的就是:
    要从键盘读取数据,但是用户又没有输入,就会阻塞

所以打开文件之后
1,磁盘中的文件的属性交给struct flie用来初始化了
2,磁盘文件的部分(或者全部)内容(因为预加载/需要使用)就会被写入到内核缓冲区中



修改

  1. 先检查用户想要修改部分是否已经在内核缓冲区中
    如果在:
    就直接把这部分拷贝到对应执行修改任务的进程中,进行修改
    如果不在:
    就调用磁盘的读接口,把要修改部分读取到内核缓冲区中,再拷贝到用户的进程那里进行修改

  2. 修改完成之后,再拷贝回内核缓冲区,等到合适的时候,再调用磁盘写接口写入到磁盘中

为什么要有这个文件内核缓冲区?

①写入外设角度:
数据在内存中“流动”比在内存和外设之间快的多
如果每次写入操作都之间写入到外设,就会多次IO,效率低
有了缓冲区,内存多次写入时,就可以把数据都拷贝进缓冲区中,时机合适再写入,此时只需要向外设写入一次就行

②从读取角度:
用户打开文件之后,可以一次性读取较多的文件内容到缓冲区中,也就是预加载
虽然用户要使用的数据不一定在里面,但有的大概率在里面
就算不在,也可以把用户想要的数据附近的数据全部加载进来,这样命中率也能提高

所以内核缓冲区的存在能大大提高IO的效率

每一个struct flie都有一个自己的内核缓冲区

一个文件只有一个内核级缓冲区

在内存中,一个文件的内容和属性不会被重复加载
即:一个被打开的文件只会出现一份inode,一份内核级缓冲区

所有打开这个文件的进程,共用一个inode和文件内核级缓冲区
因为不同进程打开同一个文件时,struct file是不一样的
打开方式和读写位置等文件操作信息是记录在struct file中的
而且系统会对文件的内核缓冲区使用同步互斥机制,保证数据一致性
所以共享同一个缓冲区没问题

相关文章:

文件【Linux操作系统】

文章目录 文件前置知识访问文件之前&#xff0c;为什么文件必须打开&#xff1f;文件的管理 标准流标准错误流的作用是什么&#xff1f; 进程和文件的关系在用户层面文件描述符是访问文件的唯一方式&#xff0c;因为系统调用接口只能通过文件描述符来找到对应的文件 操作文件的…...

PVT曲线:预测高分子材料收缩与翘曲的“热力学密码”

在高分子材料的广阔领域中&#xff0c;PVT 曲线作为一种关键的研究工具&#xff0c;正逐渐展现出其不可忽视的重要性。PVT 曲线&#xff0c;即聚合物材料的压力&#xff08;Pressure&#xff09;、体积&#xff08;Volume&#xff09;和温度&#xff08;Temperature&#xff09…...

IDEA中Quarkus框架(3.13版本)容器编排、压测与调优、注意事项等

Quarkus框架学习的第一部分&#xff0c;请访问&#xff1a; IDEA中Quarkus框架(3.13版本)开发、调试、部署、打包等 五、docker-compose容器编排 1、创建编排文件 cd quarkus-helloworldvi docker-compose.ymldocker-compose.yml内容如下&#xff1a; # yaml 配置实例 ver…...

vue+django+LSTM微博舆情分析系统 | 深度学习 | 食品安全分析

文章结尾部分有CSDN官方提供的学长 联系方式名片 文章结尾部分有CSDN官方提供的学长 联系方式名片 关注B站&#xff0c;有好处&#xff01; 编号&#xff1a; D031 LSTM 架构&#xff1a;vuedjangoLSTMMySQL 功能&#xff1a; 微博信息爬取、情感分析、基于负面消极内容舆情分析…...

CSS初识

CSS能够对⽹⻚中元素位置的排版进⾏像素级精确控制,实现美化⻚⾯的效果.能够做到⻚⾯的样式和结构分离。 可以理解给页面化妆&#xff0c;美化排版。 基本语法规范 选择器{⼀条/N条声明} 选择器决定针对谁修改(找谁) 声明决定修改啥(⼲啥) 声明的属性是键值对&#xff0c…...

Kafka 主题设计与数据接入机制

一、前言&#xff1a;万物皆流&#xff0c;Kafka 是入口 在构建实时数仓时&#xff0c;Kafka 既是 数据流动的起点&#xff0c;也是后续流处理系统&#xff08;如 Flink&#xff09;赖以为生的数据源。 但“消息进来了” ≠ “你就能处理好了”——不合理的 Topic 设计、接入方…...

文件系统常见函数

write系统调用 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 参数说明 fd 文件描述符&#xff0c;指向已打开的文件或设备&#xff08;如标准输出 1、文件句柄等 buf 指向待写入数据的缓冲区指针&#xff0c;支持任意数据类型&#xf…...

深入理解 G1 GC:已记忆集合(RSet)与收集集合(CSet)详解

已记忆集合&#xff08;RSet&#xff09;与收集集合&#xff08;CSet&#xff09;详解 深入理解 G1 GC&#xff1a;已记忆集合&#xff08;RSet&#xff09;与收集集合&#xff08;CSet&#xff09;详解一、 引言&#xff1a;G1 GC 的基石二、 已记忆集合 (RSet)&#xff1a;跟…...

Android Cordova 开发 - Cordova 解读初始化项目(index.html meta、Cordova.js、config.xml)

一、index.html meta 1、Content-Security-Policy &#xff08;1&#xff09;基本介绍 <meta http-equiv"Content-Security-Policy" content"default-src self data: https://ssl.gstatic.com unsafe-eval; style-src self unsafe-inline; media-src *; i…...

uv run 都做了什么?

uv run 都做了什么&#xff1f; uv run <命令> [参数...] 的主要作用是&#xff1a;在一个由 uv 管理或发现的 Python 虚拟环境中&#xff0c;执行你指定的 <命令>。它会临时配置一个子进程的环境&#xff0c;使其表现得如同该虚拟环境已经被激活一样。这意味着&am…...

Maven 依赖坐标与BOM统一管理

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

UV: Python包和项目管理器(从入门到不放弃教程)

目录 UV: Python包和项目管理器&#xff08;从入门到不放弃教程&#xff09;1. 为什么用uv&#xff0c;而不是conda或者pip2. 安装uv&#xff08;Windows&#xff09;2.1 powershell下载2.2 winget下载2.3 直接下载安装包 3. uv教程3.1 创建虚拟环境 (uv venv) 4. uvx5. 此pip非…...

32单片机——GPIO的工作模式

1、GPIO GPIO&#xff08;General Purpose Input Output&#xff0c;通用输入输出端口&#xff09;是控制或者采集外部器件的信息的外设&#xff0c;即负责输入输出。它按组分配&#xff0c;每组16个IO口&#xff0c;组数视芯片而定。STM32F103ZET6芯片是144脚的芯片&#xff0…...

Science Robotics 新型层级化架构实现250个机器人智能组队,“单点故障”系统仍可稳定运行

近期&#xff0c;比利时布鲁塞尔自由大学博士生朱炜煦与所在团队提出了一种创新的机器人群体架构——“自组织神经系统”&#xff08;SoNS&#xff0c;Self-organizing Nervous System&#xff09;。 它通过模仿自然界中的生物神经系统的组织原理&#xff0c;为机器人群体建立了…...

【HFP】蓝牙HFP协议来电处理机制解析

目录 一、协议概述与技术背景 1.1 HFP协议演进 1.2 核心角色定义 1.3 关键技术指标 二、来电接入的核心交互流程 2.1 基础流程概述&#xff1a;AG 的 RING 通知机制 2.2 HF 的响应&#xff1a;本地提醒与信令交互 三、带内铃声&#xff08;In-Band Ring Tone&#xff0…...

03-谷粒商城笔记

一个插件的install和生命周期的报错是不一样的 Maven找不到ojdbc6和sqljdbc4依赖包 这时候我找到了jar包&#xff0c;然后我就先找到一个jar安装到了本地仓库。 在终端上进行命令了&#xff1a; mvn install:install-file -DfileD:\ojdbc6-11.2.0.4.jar -DgroupIdcom.oracle …...

PHP 反序列化CLI 框架类PHPGGC 生成器TPYiiLaravel 等利用

# 反序列化链项目 -PHPGGC&NotSoSecure -NotSoSecure https://github.com/NotSoSecure/SerializedPayloadGenerator 为了利用反序列化漏洞&#xff0c;需要设置不同的工具&#xff0c;如 YSoSerial(Java) 、 YSoSerial.NET 、 PHPGGC 和它的先决条件。 Deserializati…...

LeetCode热题100——283. 移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0] 输出:…...

C++入门小馆: 探寻vector类

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…...

力扣hot100_链表(3)_python版本

一、25. K 个一组翻转链表 1.1、206. 反转链表 py代码 class ListNode:def __init__(self, val0, next node):self.val valself.next next class Solution:def reverseList(self, head):pre Nonecur headwhile cur:next cur.nextcur.next prepre curcur nextreturn p…...

Lua 第9部分 闭包

在 Lua 语言中&#xff0c;函数是严格遵循词法定界的第一类值。 “第一类值”意味着 Lua 语言中的函数与其他常见类型的值&#xff08;例如数值和字符串&#xff09;具有同等权限&#xff1a; 一个程序可以将某个函数保存到变量中&#xff08;全局变量和局部变量均可&a…...

【Linux】冯诺依曼体系结构及操作系统架构图的具体剖析

目录 一、冯诺依曼体系结构 1、结构图 2、结构图介绍&#xff1a; 3、冯诺依曼体系的数据流动介绍 4、为什么在该体系结构中要存在内存&#xff1f; 二、操作系统架构图介绍 1、操作系统架构图 2、解析操作系统架构图 3、为什么要有操作系统&#xff1f; 前些天发现了一…...

解析虚拟机与Docker容器化服务的本质差异及Docker核心价值

解析虚拟机与Docker容器化服务的本质差异及Docker核心价值 1.1 硬件虚拟化与操作系统级虚拟化 虚拟机&#xff08;VM&#xff09;基于硬件级虚拟化技术&#xff08;Hypervisor&#xff09;&#xff0c;通过模拟完整硬件栈&#xff08;CPU、内存、存储、网络&#xff09;创建独…...

FreeRTOS深度解析:队列集(Queue Sets)的原理与应用

FreeRTOS深度解析&#xff1a;队列集&#xff08;Queue Sets&#xff09;的原理与应用 什么是队列集&#xff1f; 在FreeRTOS中&#xff0c;队列集&#xff08;Queue Sets&#xff0c;英文名xQueueSet&#xff09;是一种强大的数据结构&#xff0c;用于高效管理多个队列。它的…...

java将pdf转换成word

1、jar包准备 在项目中新增lib目录&#xff0c;并将如下两个文件放入lib目录下 aspose-words-15.8.0-jdk16.jar aspose-pdf-22.9.jar 2、pom.xml配置 <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId><versi…...

网络原理 - 6

目录 4. 滑动窗口 滑动窗口出现丢包 情况一&#xff1a;数据报已经抵达&#xff0c;ACK 被丢了​编辑 情况二&#xff1a;数据报直接就丢了 5. 流量控制 完&#xff01; 4. 滑动窗口 这个滑动窗口是 TCP 中非常有特点的机制。 我们知道&#xff0c;TCP 是通过确认应答&…...

【Linux网络】构建类似XShell功能的TCP服务器

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

Spring AI - Redis缓存对话

先看效果 对话过程被缓存到了Redis 中。 原理 在上一节我们快速入门了SpringAI&#xff0c;具体文章请查看&#xff1a;快速入门Spring AI 创建 ChatClient 的代码如下&#xff1a; this.chatClient ChatClient.builder(chatModel).defaultSystem(DEFAULT_PROMPT).defaultAd…...

rk3588 驱动开发(二)第四章嵌入式 Linux LED 驱动开发实验

4.1 Linux 下 LED 灯驱动原理 Linux 下的任何外设驱动&#xff0c;最终都是要配置相应的硬件寄存器。所以本章的 LED 灯驱动 最终也是对 RK3588 的 IO 口进行配置&#xff0c;与裸机实验不同的是&#xff0c;在 Linux 下编写驱动要符合 Linux 的驱动框架。开发板上的 LED 连接…...

第49讲:AI驱动的农业碳汇估算与生态价值评估 —— 打造更“绿”的智慧农业未来

目录 🌍 一、农业碳汇:我们为什么要关心它? 🤖 二、AI是如何介入农业碳汇评估的? 🛠 三、案例实战:AI估算区域农田碳汇储量 📍 场景设定: 📊 数据来源: 🔁 处理流程: 📈 四、生态价值评估:从碳储量到生态效益 🧭 五、平台与工具推荐 💬 六、…...

springmvc入门案例

目录 前言 springmvc概述 springmvc入门案例&#xff08;使用配置类替代原本的web.xml) 第一步、创建一个web工程 第二步、引入相应的依赖&#xff08;servlet-api、spring-webmvc、&#xff09; 第三步、编写 SpringMVC配置类&#xff0c;并开启包扫描功能 第四步、编写…...

Node.js学习

概述 Node.js 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境&#xff0c;允许在服务器端运行 JavaScript 代码。它采用事件驱动和非阻塞 I/O 模型&#xff0c;适合构建高性能、可扩展的网络应用&#xff0c;尤其擅长处理实时应用和大规模数据密集型场景 背景 JavaScri…...

SQL注入漏洞中会使用到的函数

目录 一、信息获取函数 1. 通用函数 2. 元数据查询&#xff08;INFORMATION_SCHEMA&#xff09; 二、字符串操作函数 1. 字符串连接 2. 字符串截取 3. 编码/解码 三、报错注入专用函数 1. MySQL 2. SQL Server 3. PostgreSQL 四、时间盲注函数 1. 通用延迟 2. 计…...

MIT IDSS深度解析:跨学科融合与系统科学实践

麻省理工学院的IDSS(Institute for Data, Systems, and Society, IDSS)是一个致力于通过先进分析方法推动教育与研究的前沿机构。它将工程学、信息科学和数据科学的方法与社会科学的分析方法相结合,以应对复杂的社会挑战。 MIT IDSS 建立在统计学、计算机科学和特定应用领域…...

重塑智慧出行新生态,德赛西威全新战略愿景发布

4月22日&#xff0c;上海车展开幕前夕&#xff0c;德赛西威以“智新境&#xff0c;向远大”为主题&#xff0c;正式对外发布全新发展战略及使命、愿景&#xff1b;同时&#xff0c;代表未来AI出行趋势的智慧出行解决方案Smart Solution 3.0重磅亮相。 一、把握变革节点 创领产…...

全面解析 classification_report:评估分类模型性能的利器

解读 classification_report 的使用&#xff1a;评估分类模型性能的关键工具 在机器学习中&#xff0c;分类任务是最常见的应用场景之一。无论是垃圾邮件过滤、图像识别还是情感分析&#xff0c;分类模型的性能评估都是至关重要的一步。而 classification_report 是 Scikit-le…...

Qt案例 使用QFtpServerLib开源库实现Qt软件搭建FTP服务器,使用QFTP模块访问FTP服务器

本以为搭建和访问FTP服务器的功能已经是被淘汰的技术了&#xff0c;只会在学习新技术的时候才会了解学习学习&#xff0c;WinFrom版本&#xff0c;和windows Api版本访问FTP服务器的功能示例也都写过。没想到这次会在项目中再次遇到&#xff0c; 这里记录下使用Qt开源库QFtpSer…...

图像后处理记录

图像后处理记录 ocr后处理记录 opencv裁剪 编译命令 cmake -S . -B build-x64 -DBUILD_LIST"core,imgproc,imgcodecs,highgui" -DBUILD_SHARED_LIBSOFF -DBUILD_opencv_appsOFF -DBUILD_opencv_jsOFF -DBUILD_ANDROID_PROJECTSOFF -DBUILD_ANDROID_EXAMPLESOFF -…...

解决element中的el-anchor链接被作为路由跳转导致页面404

解决element中的el-anchor链接被作为路由跳转导致页面404 问题&#xff1a; 在使用elementPlus时&#xff0c;el-anchor-link中的href被识别为路由进行跳转&#xff0c;导致不能正常跳转到锚点&#xff0c;且页面显示404。 解决&#xff1a;自定义方法解决 <!--添加hand…...

Mapreduce中maven打包

MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff08;例如&#xff1a;jar包&#xff09;&#xff0c;并发运行在…...

C++初阶——string的使用(下)

C初阶——string的使用&#xff08;下&#xff09; 一、string类对象的容量操作 对于string的容量操作&#xff0c;我们可以通过顺序表来理解&#xff0c;顺序表是通过动态数组来实现的&#xff0c;在数据结构专栏的第一篇就是顺序表的详细讲解&#xff0c;链接如下&#xff…...

AIGC vs 人类创作者:是竞争还是协作?

AIGC vs 人类创作者&#xff1a;是竞争还是协作&#xff1f; 随着人工智能技术的飞速发展&#xff0c;特别是生成式AI&#xff08;AIGC, AI-Generated Content&#xff09;的崛起&#xff0c;越来越多的领域开始出现AI的身影。从文本创作、图像生成到音乐制作&#xff0c;AIGC…...

Stable Baselines3 结合 gym 训练 CartPole 倒立摆

视频讲解&#xff1a; Stable Baselines3 结合 gym 训练 CartPole 倒立摆 今天介绍下stable_baselines3和gym&#xff0c;可以方便实现DL的实现&#xff0c;应用在机械臂catch、reach等场景 测试代码仓库&#xff1a;https://github.com/LitchiCheng/DRL-learning.git https:…...

ctfshow web8

前言 学习内容&#xff1a;简单的盲注脚本的书写 web8 这个题目题目手动注入很麻烦 主要是他过滤了 union 空格和 过滤了union的解决方法 1、使用盲注(报错注入和盲注) 2、使用时间盲注 3、堆叠注入 盲注脚本的书写 首先他是有注入点的 然后熟悉requests包的使用 …...

Linux程序地址空间

目录 研究背景 程序地址空间回顾 来段代码感受一下 进程地址空间 Linux2.6内核进程调度队列 一个CPU拥有一个runqueue 优先级 活跃队列&#xff08;只出不进&#xff09; 过期队列&#xff08;只进不出&#xff09; active指针和expired指针 总结 研究背景 Linux内核版本&#…...

破茧成蝶:阿里云应用服务器让传统 J2EE 应用无缝升级 AI 原生时代

丝滑升级拥抱大模型&#xff1a;详解AI时代的应用智能化升级路径 破茧成蝶&#xff1a;阿里云应用服务器让传统 J2EE 应用无缝升级AI原生时代 ——十年代码无需重写&#xff0c;三步开启智能化跃迁 作者&#xff1a;孤弋、孚阳 序幕&#xff1a;一场跨越 20 年的技术对话 在杭…...

游戏引擎学习第240天:将渲染器移至第三层

这节又枯燥又无聊简直了 回顾并为今天的内容做铺垫 昨天我们说到&#xff0c;想对渲染器和平台层的集成方式做一些修改。我们之前简单讲了一下修改的目的&#xff1a;我们希望游戏本身不再直接调用 OpenGL 的渲染代码&#xff0c;而是只生成一组渲染指令缓冲区&#xff0c;然…...

2025.04.23华为机考第三题-300分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 03. 时空旅行者的最优路径 问题描述 A先生是一名时空旅行者,他可以在不同的时空点之间穿梭。每次从一个时空点跳跃到另一个时空点需要消耗一个时间单位。在每个时空点,都有一些特…...

Kafka 保证多分区的全局顺序性的设计方案和具体实现

Kafka 本身无法直接保证多分区的全局顺序性&#xff0c;因为分区设计旨在并行处理以提升吞吐量。 要实现多分区的顺序性&#xff0c;可尝试通过以下方法在系统层面或业务逻辑上解决&#xff1a; 一、方案设计 单一分区路由&#xff08;还是将消息发送到同一分区&#xff09;&a…...

数据结构初阶:二叉树(四)

概述&#xff1a;本篇博客主要介绍链式结构二叉树的实现。 目录 1.实现链式结构二叉树 1.1 二叉树的头文件&#xff08;tree.h&#xff09; 1.2 创建二叉树 1.3 前中后序遍历 1.3.1 遍历规则 1.3.1.1 前序遍历代码实现 1.3.1.2 中序遍历代码实现 1.3.1.3 后序遍历代…...