【Linux】文件系统:文件fd

🔥个人主页:Quitecoder
🔥专栏:linux笔记仓

目录
- 01.回顾C文件接口
- 02.系统文件I/O
- 02.1 open
- `flags` 参数(文件打开模式)标记位传参
- 1. 访问模式(必须指定一个)
- 2. 额外控制标志(可选,可组合使用)
- 3. `mode` 参数(仅 `O_CREAT` 生效)
- 02.2 open函数返回值fd(文件描述符)
- 03.fd理解
01.回顾C文件接口
#include<stdio.h>int main()
{FILE *fp=fopen("log.txt","w");if(fp==NULL){perror("fopen");return 1;}fclose(fp);return 0;
}
我们进行文件操作,前提是我们的代码跑起来了,文件的打开和关闭,是cpu在执行我们的代码
打开文件:本质是进程打开文件
文件没有被打开的时候,存储在磁盘中
一个进程可以打开多个文件,系统中可以启动很多进程,OS内部一定存在大量被打开的文件,操作系统对这些文件进行管理(先描述再组织,类似PCB)
文件=属性+内容
FILE *fp=fopen("log.txt","w");
- 如果不存在,则在当前路径下,新建指定的文件
- 默认打开文件的时候,会把目标文件清空


> 可以用来新建文件,清空文件,先清空再写入
输出重定向一定是文件操作!
打开文件的方式:
r Open text file for reading. The stream is positioned at the beginning of the file.r+ Open for reading and writing.The stream is positioned at the beginning of the file.w Truncate(缩短) file to zero length or create text file for writing.The stream is positioned at the beginning of the file.w+ Open for reading and writing.The file is created if it does not exist, otherwise it is truncated.The stream is positioned at the beginning of the file.a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.a+ Open for reading and appending (writing at end of file).The file is created if it does not exist. The initial file positionfor reading is at the beginning of the file, but output is always appended to the end of the file.
| 模式 | 描述 | 文件指针位置 | 文件是否会创建 | 文件是否会被截断(清空) |
|---|---|---|---|---|
r | 只读模式,文件必须存在 | 开始位置 | 否 | 否 |
r+ | 读写模式,文件必须存在 | 开始位置 | 否 | 否 |
w | 写入模式,文件不存在时会创建,存在时会清空文件 | 开始位置 | 是 | 是 |
w+ | 读写模式,文件不存在时会创建,存在时会清空文件 | 开始位置 | 是 | 是 |
a | 追加模式,文件不存在时会创建,存在时内容追加到文件末尾 | 文件末尾 | 是 | 否 |
a+ | 读写追加模式,文件不存在时会创建,存在时内容追加到文件末尾 | 开始位置(读取)/文件末尾(写入) | 是 | 否 |
02.系统文件I/O
文件->磁盘->外设->硬件
向文件中写入,本质是向硬件中写入,用户没有权利直接写入,通过OS写入,OS必须给我们提供系统调用
fopen/fwrite/fread/fprintf/scanf/printf/cin/cout 我们用的c/c++都是对系统调用接口的封装!
02.1 open

open 是 Unix/Linux 系统中用于打开或创建文件的系统调用,位于 fcntl.h 头文件中。它用于以不同的模式访问文件,如只读、写入、追加等。
1. open 函数原型
在 C 语言中,open 的函数原型如下:
#include <fcntl.h> // 文件控制选项
#include <sys/types.h> // 类型定义
#include <sys/stat.h> // 文件属性
#include <unistd.h> // 通用 APIint open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
2. 参数解析
pathname:要打开的文件路径。flags:指定文件的访问模式(只读、读写等)和其他选项(创建文件、截断等)。mode:用于设置新文件的权限(仅当O_CREAT选项被使用时有效),通常采用0644或0666形式。
3. 返回值
- 成功:返回一个文件描述符(非负整数),用于后续的
read、write、close操作。 - 失败:返回
-1,并设置errno变量来指示错误类型。
flags 参数(文件打开模式)标记位传参
在系统调用(如 open())中,flags 是一个 位掩码(bitmask),用于控制函数的行为。例如,在 open() 中,flags 用于指定文件的打开模式(只读、只写、读写等)以及额外的选项(创建、追加、非阻塞等)。
位掩码 是指使用二进制位的不同组合来表示多种选项,这样可以通过按位或 (|) 来组合多个标志,而不会相互影响。
1. 访问模式(必须指定一个)
访问模式决定了文件的读写权限,这三者不能同时使用,否则会报错。
| 标志 | 值(十六进制) | 说明 |
|---|---|---|
O_RDONLY | 0x0000 | 只读模式(Read Only) |
O_WRONLY | 0x0001 | 只写模式(Write Only) |
O_RDWR | 0x0002 | 读写模式(Read & Write) |
示例
int fd = open("file.txt", O_RDONLY); // 以只读模式打开文件
int fd = open("file.txt", O_WRONLY); // 以只写模式打开文件
int fd = open("file.txt", O_RDWR); // 以读写模式打开文件
2. 额外控制标志(可选,可组合使用)
这些标志可以与访问模式组合使用,以改变 open() 的行为。
| 标志 | 值(十六进制) | 说明 |
|---|---|---|
O_CREAT | 0x0040 | 若文件不存在,则创建新文件(需要 mode 参数) |
O_EXCL | 0x0080 | 与 O_CREAT 组合,文件必须不存在,否则失败 |
O_TRUNC | 0x0200 | 若文件已存在,则清空文件内容 |
O_APPEND | 0x0400 | 追加模式,写入时自动跳到文件末尾 |
O_NONBLOCK | 0x0800 | 以非阻塞模式打开文件(常用于设备文件、网络通信) |
O_SYNC | 0x101000 | 使 write 操作同步到磁盘,保证数据立即写入 |
O_NOFOLLOW | 0x20000 | 如果文件是符号链接,则 open() 失败 |
3. mode 参数(仅 O_CREAT 生效)
当 flags 包含 O_CREAT 时,需要提供 mode 参数,表示新建文件的权限,例如:
open("newfile.txt", O_WRONLY | O_CREAT, 0644);
其中 0644 代表:
0:八进制数前缀6(110):用户(拥有者)可读可写4(100):组(Group)只读4(100):其他人(Others)只读
如何组合 flags
由于 flags 是位掩码(bitmask),可以使用按位或 | 运算符来组合多个标志。例如:
int fd = open("file.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
O_RDWR(读写模式)O_CREAT(如果文件不存在,则创建)O_TRUNC(如果文件已存在,则清空内容)
等价于:
flags = 0x0002 | 0x0040 | 0x0200; // 计算出的十六进制值
flags 具体的二进制表示
假设 flags 组合如下:
int flags = O_RDWR | O_CREAT | O_APPEND;
如果 O_RDWR = 0x0002,O_CREAT = 0x0040,O_APPEND = 0x0400,那么它们的二进制表示如下:
O_RDWR = 0000 0000 0000 0010 (0x0002)
O_CREAT = 0000 0000 0100 0000 (0x0040)
O_APPEND = 0000 0100 0000 0000 (0x0400)
--------------------------------
组合后 = 0000 0100 0100 0010 (0x0442)
当 open() 处理 flags 时,它会解析这个二进制值,并执行相应的操作。
flags是open()的核心参数,用于控制文件的访问模式和特殊行为。- 访问模式(
O_RDONLY、O_WRONLY、O_RDWR)必须指定一个。 - 可以通过按位或
|组合多个控制标志(如O_CREAT、O_TRUNC、O_APPEND)。 mode参数用于O_CREAT,指定新文件的权限,如0644。open()返回文件描述符(fd),失败时返回-1并设置errno。
这种flags的传递位图标记位的方法在OS系统调用接口中很常见,我们可以自己设计一个传递位图标记位的函数:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>#define ONE 1 //1 0000 0001
#define TWO (1<<1) //2 0000 0010
#define THREE (1<<2) //4 0000 0100
#define FOUR (1<<3) //8 0000 1000void print(int flag)
{if(flag&ONE)printf("one\n");if(flag&TWO)printf("two\n");if(flag&THREE)printf("three\n");if(flag&FOUR)printf("four\n");
}int main()
{print(ONE);printf("\n");print(TWO);printf("\n");print(THREE);printf("\n");print(ONE|TWO);printf("\n");print(ONE|THREE);printf("\n");print(ONE|TWO|THREE|FOUR);printf("\n");return 0;
}
演示了如何使用位运算来检查不同的标志(flag)。程序中的关键部分是 print 函数,它检查传入的 flag 参数,并根据不同的位值输出相应的文本。
让我们逐步分析每个部分。
宏定义
#define ONE 1 //1 0000 0001
#define TWO (1<<1) //2 0000 0010
#define THREE (1<<2) //4 0000 0100
#define FOUR (1<<3) //8 0000 1000
这部分定义了四个宏,每个宏的值都代表一个特定的二进制位:
ONE = 1:二进制0000 0001,表示第 0 位(从右向左数)。TWO = 2:二进制0000 0010,表示第 1 位。THREE = 4:二进制0000 0100,表示第 2 位。FOUR = 8:二进制0000 1000,表示第 3 位。
使用 1 << n 来左移 1 位 n 次,从而生成一个表示 2 的幂的二进制值。
print 函数
void print(int flag)
{if(flag&ONE)printf("one\n");if(flag&TWO)printf("two\n");if(flag&THREE)printf("three\n");if(flag&FOUR)printf("four\n");
}
print 函数通过位运算 &(按位与运算)检查给定 flag 中每一位是否设置为 1。如果某一位为 1,就会输出相应的文本。
flag & ONE:检查flag的第 0 位(ONE)。flag & TWO:检查flag的第 1 位(TWO)。flag & THREE:检查flag的第 2 位(THREE)。flag & FOUR:检查flag的第 3 位(FOUR)。
输出说明:
print(ONE)传入ONE(即1,二进制0000 0001),因此检查到第 0 位为 1,输出one。print(TWO)传入TWO(即2,二进制0000 0010),因此检查到第 1 位为 1,输出two。print(THREE)传入THREE(即4,二进制0000 0100),因此检查到第 2 位为 1,输出three。print(ONE | TWO)传入ONE | TWO(即1 | 2 = 3,二进制0000 0011),因此第 0 位和第 1 位都为 1,输出one和two。print(ONE | THREE)传入ONE | THREE(即1 | 4 = 5,二进制0000 0101),因此第 0 位和第 2 位都为 1,输出one和three。print(ONE | TWO | THREE | FOUR)传入ONE | TWO | THREE | FOUR(即1 | 2 | 4 | 8 = 15,二进制0000 1111),因此所有四个标志位都为 1,输出one、two、three和four。
onetwothreeone
twoone
threeone
two
three
four
这个例子很有用,展示了如何使用位操作进行标志位管理,尤其是在处理多个选项或功能时
4. open 与 fopen 的区别
| 对比项 | open(系统调用) | fopen(标准库函数) |
|---|---|---|
| 头文件 | <fcntl.h> | <stdio.h> |
| 返回值 | 文件描述符(int) | FILE* 指针 |
| 模式 | 需要手动指定 flags | 类似 "r", "w", "a" 等 |
| 缓冲 | 无缓冲,直接访问内核 | 有缓冲,性能更优 |
| 适用场景 | 底层 I/O 操作 | 高级文件读写操作 |
- 如果只是进行简单的文件读写,建议使用
fopen,因为它提供了缓冲,效率更高。 - 如果需要进行更底层的文件控制(如非阻塞、文件锁定等),则使用
open。
02.2 open函数返回值fd(文件描述符)
write函数原型:
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
int main()
{umask(0);int fd=open("file.txt",O_WRONLY | O_CREAT,0666);if(fd<0){perror("open");return 1;}const char *message = "hello linux\n";write(fd,message,strlen(message));close(fd);return 0;
}

此时如果我们重新写入aaaaa:

这里的文件内容老的没有被清空,这里跟open那里fd传入flags参数有关,我们这里传入O_TRUNC,每次打开文件时清空即可

int fd=open("file.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
写方式打开,不存在就创建,存在就先清空!
在认识返回值之前,先来认识一下两个概念: 系统调用 和 库函数
上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
而, open close read write lseek 都属于系统提供的接口,称之为系统调用接口

所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发
接下来看fd
fd是open的返回值,也是文件描述符,我们这里设置代码来打印出它的值
int main()
{int fda=open("loga.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fda:%d\n",fda);int fdb=open("logb.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdb:%d\n",fdb);int fdc=open("logc.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdc:%d\n",fdc);int fdd=open("logd.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdd:%d\n",fdd);return 0;
}

文件描述符数字为3 4 5 6
Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.
0,1,2对应的物理设备一般是:键盘,显示器,显示器
C 语言的标准流与操作系统的文件描述符是关联的。
- 标准输入(stdin):与文件描述符 0 相关联。
- 标准输出(stdout):与文件描述符 1 相关联。
- 标准错误(stderr):与文件描述符 2 相关联
这些文件描述符在程序启动时由操作系统自动分配并打开,且在大多数情况下它们指向终端或控制台。如果没有显式地进行文件重定向(例如使用freopen 或命令行中的重定向符号),这些文件描述符就会继续指向终端
ssize_t write(int fd, const void *buf, size_t count);
那么我们可以直接往显示器上写入:
const char *message = "aaaaa\n";
write(1,message,strlen(message));

03.fd理解

系统中有进程被task_struct管理,有很多被打开的文件,struct file 是操作系统用来表示打开文件的主要数据结构。每当一个文件被打开时,操作系统会创建一个 struct file 对象,并将其与文件描述符关联,对象之间通过双向链表连接
struct file {struct file_operations *f_op; // 文件操作的指针void *private_data; // 私有数据,用于存储文件的额外信息(如文件特定的数据结构)unsigned long f_flags; // 文件标志,描述文件的访问模式(如只读、只写、追加等)struct inode *f_inode; // 文件的 inode 节点,包含文件的元数据off_t f_pos; // 文件指针,记录当前文件的读写位置
};
struct file有指向它的缓存,磁盘中文件,属性来初始化struct file,内容加载到缓存中,未来想读修改写入直接在缓存总写入,最后刷新到磁盘中,所以对文件的管理转化为对内核struct file进行管理
那么系统中有很多的进程,右边有很多被打开的文件,那么哪些文件对应哪些进程呢?
进程是可以打开多个文件的,操作系统在PCB里存在一个属性,这个属性叫做struct files_struct *files

struct files_struct 包含一个数组,数组有对应的下标,进程需要找到一个文件,最终只需要把数组的下标返回给上层,上层只要拿着int fd就可以访问文件了!
所以文件描述符fd的本质是内核的进程的,文件映射关系数组的下标
所以文件一旦打开,我们发现,write,read,close都需要参数fd,一旦fd传入,操作系统就能知道你要访问当前系统的哪个文件
所以读文件就是把缓存中的内容拷贝到应用层,无论读写都必须在合适的时候让0S把文件的内容读到文件缓冲区中,哪怕只修改一个字节,也需要把文件内容读到缓冲区中,再刷到磁盘中
open在干什么呢?
- 创建file
- 开辟文件缓冲区的空间,加载文件数据(延后)
- 查进程的文件措述符表
- file地址,填入对应的表下标中
- 返回下标
我们已经理解了什么是fd,我们前面提到0 1 2是默认打开了,分别对应键盘,显示器,显示器,三个硬件,如何理解它呢?
我们需要理解,linux,一切皆为文件

在linux层面上他是怎么做到的呢?
对于每一种设备,我们需要关心的是它的属性和操作方法,
最重要的是关注它的操作方法,对于键盘来讲,需要有自己的读方法,写方法,对于显示器,也要有自己的读方法,写方法。冯诺依曼体系中,键盘作为外设,那么这个写方法设置为空函数,显示器对应的读方法也没办法实现
不同的设备,每一种设备的操作方法一定是不一样的,这一层是由驱动层来完成的
每一个被打开的设备,在操作系统层面,为设备构建struct file,虽然底层的方法不同,但是我可以把参数和返回值设为类似的,这里OS设置函数指针。所以如果我们想要访问键盘,找到键盘的struct file,调用read,从struct file视角往上看,上层看到所有的设备一切皆文件
这里是c语言实现的多态技术,进程统一认为struct file
这里的文件层,我们成为虚拟文件系统
虚拟文件系统(VFS,Virtual File System)是操作系统中的一个抽象层,它为不同类型的文件系统(如ext4、NTFS、FAT、NFS 等)提供了一个统一的接口。通过VFS,操作系统能够以一致的方式访问和管理不同类型的文件系统,无论是本地磁盘文件系统还是网络文件系统。这使得文件系统的实现与用户或应用程序的使用方式解耦,增强了操作系统的灵活性和可扩展性

在操作系统内访问文件时,系统只认文件描述符
那么如何理解c语言通过FILE*访问文件呢?
FILE*:是 C 标准库提供的文件操作接口,它是一个指向 FILE 结构的指针。C 标准库通过 FILE* 为程序员提供了一套更为友好的文件操作函数,如 fopen、fread、fwrite、fclose 等。FILE* 实际上是对文件描述符的封装,提供了缓冲区管理、错误处理等功能

c语言为什么要这么做?
对于系统调用,不同系统调用接口不一样,这样的代码不具有跨平台性。所有的语言都想有跨平台性,所有的语言对不同平台系统的系统调用进行封装,不同语言封装的时候,文件接口就有差别了

相关文章:
【Linux】文件系统:文件fd
🔥个人主页:Quitecoder 🔥专栏:linux笔记仓 目录 01.回顾C文件接口02.系统文件I/O02.1 openflags 参数(文件打开模式)标记位传参1. 访问模式(必须指定一个)2. 额外控制标志…...
电脑系统损坏,备份文件
一、工具准备 1.U盘:8G以上就够用,注意会格式化U盘,提前备份U盘内容 2.电脑:下载Windows系统并进行启动盘制作 二、Windows启动盘制作 1.微软官网下载启动盘制作工具微软官网下载启动盘制作工具https://www.microsoft.com/zh-c…...
View Binding小记
View Binding 1.简介 View Binding 是 Android 开发中的一项功能,它允许开发者以类型安全的方式直接访问布局文件中的视图,而无需使用 findViewById View Binding 生成的绑定类中的字段类型与布局文件中的视图类型完全一致,避免了 findVie…...
Python网络运维自动化:从零开始学习NetDevOps
零基础入门NetDevOps,让网络运维更简单、更高效。 Python网络运维自动化 1.从理论到实战:从基础理论入手,通过实战案例教学,手把手教读者掌握Python网络运维自动化,解决运维工作中的日常问题,提升运维效率…...
公网远程家里局域网电脑过程详细记录,包含设置路由器。
由于从校内迁居小区,校内需要远程控制访问小区内个人电脑,于是早些时间刚好自己是电信宽带,可以申请公网ipv4不需要花钱,所以就打电话直接申请即可,申请成功后访问光猫设备管理界面192.168.1.1,输入用户名密码登录超管(密码是网上查下就有了)设置了光猫为桥接模式,然后…...
网络安全示意图 网络安全路线图
其实网络安全本身的知识点并不算难,但需要学的东西比较多,如果想要从事网络安全领域,肯定是需要系统、全面地掌握清楚需要用到的技能的。 自学的方式基本是通过看视频或者相关的书籍,不论是什么方法,都是很难的&#…...
【多线程异步和MQ有什么区别?】
多线程异步和MQ有什么区别? 多线程异步MQ(消息队列)多线程异步与MQ的区别多线程异步 概念: 多线程异步是指在单个应用程序内部创建和管理多个线程,这些线程并行处理任务。 多线程主要用于提升应用程序的性能,特别是在处理计算密集型任务(如科学计算、图像处理、数据分…...
Annie导航2.0 新增加5个模版 开源免授权
新增5个模版 修复部分模版样式问题 采用最新技术tinkphp8.0 php8.1 mysql5.7 Funadmin框架 后台一键式统计访问人数 网站设置 分类设置 网站管理 工具管理 友情链接 广告管理 [color=var(–comiis-color)]联系方式 主题管理 配置多套模版随意切换 已更新市面上热门的几个模版...
Spring AI发布!让Java紧跟AI赛道!
1. 序言 在当今技术发展的背景下,人工智能(AI)已经成为各行各业中不可忽视的重要技术。无论是在互联网公司,还是传统行业,AI技术的应用都在大幅提升效率、降低成本、推动创新。从智能客服到个性化推荐,从语…...
一个简洁高效的Flask用户管理示例
Flask-Login 是 Flask 的用户管理扩展,提供 用户身份验证、会话管理、权限控制 等功能。 适用于: • 用户登录、登出 • 记住用户(“记住我” 功能) • 限制未登录用户访问某些页面 • 用户会话管理 1. 安装 Flask-Login pi…...
HTML之JavaScript Form表单事件
HTML之JavaScript Form表单事件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title…...
[文末数据集]ML.NET库学习010:URL是否具有恶意性分类
文章目录 ML.NET库学习010:URL是否具有恶意性分类项目主要目的和原理项目概述主要功能和步骤总结数据集地址ML.NET库学习010:URL是否具有恶意性分类 项目主要目的和原理 项目主要目的: 本项目的目的是通过分析URL的特征,构建一个机器学习模型来判断给定的URL是否具有恶意…...
百度地图接入DeepSeek技术解析:AI如何重塑地图搜索体验?
百度地图接入DeepSeek技术解析:AI如何重塑地图搜索体验? 百度地图接入DeepSeek技术解析:AI如何重塑地图搜索体验?引言一、技术背景与核心能力1.1 DeepSeek的技术优势1.2 百度地图API的技术底座 二、技术实现路径2.1 系统架构设计2…...
C语言——深入理解指针(2)(数组与指针)
文章目录 数组名的理解使用指针访问数组一维数组传参的本质冒泡排序二级指针指针数组指针数组模拟二维数组 数组名的理解 之前我们在使用指针访问数组内容时,有这样的代码: int arr[10]{1,2,3,4,5,6,7,8,9,10}; int* p&arr[0];这里我们使用&ar…...
Open-WebUI官方部署文档
Github地址:GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 打开 WebUI 👋 如果你是零基础的小白,不知道什么是DeepSeek的话?不知道如何本地化部署,我强烈建议先看…...
爬虫破解网页禁止F12
右击页面显示如下 先点击f12再输入网址,回车后没有加载任何数据 目前的一种解决方法: 先 AltD ,再 CtrlShifti...
vuex 简单使用
vuex 简单使用 示例:管理一个对象状态 假设我们要管理一个用户对象 user,包含 name 和 age 两个属性。 1. 定义 Vuex Store 在 store/index.js 中定义状态、mutations、actions 和 getters: import { createStore } from vuex;const store…...
机器学习_16 朴素贝叶斯知识点总结
朴素贝叶斯(Naive Bayes)是一种基于贝叶斯定理的概率分类算法,广泛应用于文本分类、垃圾邮件检测和情感分析等领域。它通过计算后验概率来进行分类,核心假设是特征之间相互独立。今天,我们就来深入探讨朴素贝叶斯的原理…...
Xshell连接虚拟机ubuntu,报错(port 22): Connection failed.
Connecting to 192.168.37.131:22... Could not connect to 192.168.37.131 (port 22): Connection failed. 虚拟机ubuntu 可以ping通,但就是连接不上。 先后排查了, 1. 网络适配器是否被禁用 2.设置虚拟机网络适配器的网络连接模式为桥接模式…...
浏览器报错:无法访问此网站 无法找到xxx.xxx.net的DNS地址。正在诊断该问题。尝试运行Windows网络诊断。DNS_PROBE_STARTED
🤟致敬读者 🟩感谢阅读🟦希望我的文章能帮到您🟪如有兴趣可点关注了解更多内容 📘博主信息 点击标题👆有惊喜 📃文章前言 🔷文章均为学习和工作中整理的笔记,分享记录…...
2024年国赛高教杯数学建模C题农作物的种植策略解题全过程文档及程序
2024年国赛高教杯数学建模 C题 农作物的种植策略 原题再现 根据乡村的实际情况,充分利用有限的耕地资源,因地制宜,发展有机种植产业,对乡村经济的可持续发展具有重要的现实意义。选择适宜的农作物,优化种植策略&…...
React中如何处理高阶组件中的错误
在 React 高阶组件中处理错误是确保应用程序健壮性和稳定性的重要环节。以下是一些处理高阶组件中错误的常见方法: 1. 捕获渲染时的错误 在高阶组件中,渲染过程可能会因为各种原因(如 props 数据格式错误、组件内部逻辑异常等)抛…...
CentOS/RHEL如何更换国内Yum源
在国内使用CentOS或RHEL系统时,默认的Yum源是国外的,这可能导致软件包的下载速度慢,甚至出现连接超时的问题。为了解决这个问题,我们可以将Yum源切换到国内的镜像源,从而大大提高软件包的下载速度和稳定性。 本文将详…...
linux 替换jar包中的文件
在 Linux 系统中替换 JAR 文件中的文件,一般可以使用jar命令来完成,以下是具体步骤8: 查找目标文件在 JAR 包中的路径:使用jar tvf命令可以列出 JAR 包中的所有文件,再通过grep命令来过滤出要替换的目标文件。例如&am…...
如何系统成为高级Qt工程师?
要系统性地成为高级Qt工程师,需要从基础到进阶逐步构建知识体系,并结合实战经验、源码分析和架构设计能力的提升。以下是分阶段的系统性学习路径和建议: 一、夯实基础阶段 C++深度掌握 精通C++11/14/17特性(智能指针、lambda、移动语义等)理解面向对象设计、设计模式(如观…...
A9. Jenkins Pipeline自动化构建,飞书通知
怎么收集服务部署信息?【前置】首先Python如何操作JSON数据如何记录部署信息,什么时机统计?如何下发某一服务统计信息 ?那么怎么创建飞书通知机器人呢?编写飞书通知脚本总结下面我们接着上一篇文章《A8. Jenkins Pipeline自动化部署过程,多模块远程服务协调实战》继续往下…...
firefox升级后如何恢复收藏夹和密码的问题
手贱,无聊,看到Firefox提示说再不升级就不能使用了,结果就信了; 升级完之后,傻眼了,收藏夹无法导入,密码全没了 新版的Firefox采用snap方式安装,所以安装路径是在snap下面的&#…...
维护ceph集群
1. set: 设置标志位 # ceph osd set <flag_name> # ceph osd set noout # ceph osd set nodown # ceph osd set norecover 2. unset: 清除标志位 # ceph osd unset <flag_name> # ceph osd unset noout # ceph osd unset nodown # ceph osd unset norecover 3. 标志…...
亲测!我是如何用 Anything LLM 等搭建 AI 智能知识库的
以下是本地部署Anything LLMOllamaDeepSeek R1打造AI智能知识库的教程: 安装Ollama 下载Ollama:浏览器进入ollama.com主页,点击页面右上角或中间下端黑底的“Download”。选择对应的系统图标,如Windows用户点击“Download for W…...
汽车零部件开发应该具备哪些编程思维?
目录 1、功能安全思维 2、实时性与确定性思维 3、可靠性和冗余思维 4、硬件软件协同思维 5、CAN总线通信思维 6、故障诊断和自诊断思维 7、功耗优化思维 8、软件更新和版本管理思维 9、用户体验与安全性思维 汽车零部件开发中,嵌入式软件在车辆系统中的作用…...
