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

【嵌入式Linux应用开发基础】文件I/O基础编程

目录

一、文件I/O简介

二、文件描述符

2.1. 唯一性

2.2. 抽象性

2.3. 有限性

三、文件操作函数

四、标准文件I/O函数

五、文件执行权限

5.1. 权限类型

5.2. 权限分配对象

5.3. 权限表示方法

5.4. 权限设置命令

5.5. 权限设置的重要性

5.6. 实例说明

六、设备文件读写

6.1. 设备文件类型

6.2. 设备文件的命名

6.3. 设备文件的读写操作

6.4. 示例:串口通信


在嵌入式 Linux 应用开发中,文件 I/O(Input/Output)基础编程是非常重要的一部分,它允许程序与文件系统进行交互,实现数据的读取、写入和管理等操作。

一、文件I/O简介

Linux文件I/O是操作系统中处理文件读写操作的基本机制。在Linux系统中,文件I/O操作是通过系统调用实现的,这些系统调用允许用户空间的程序与内核空间的文件系统进行交互。一个通用的IO模型通常包括打开文件、读写文件、关闭文件这些基本操作。

  • 文件描述符(File Descriptor):在 Linux 系统中,每个打开的文件都由一个非负整数的文件描述符来标识。当程序打开一个现有文件或者创建一个新文件时,内核会返回一个文件描述符。标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)的文件描述符分别是 0、1 和 2。
  • 缓冲区(Buffer):为了提高文件 I/O 的效率,系统通常会使用缓冲区。缓冲区是一块内存区域,用于临时存储从文件读取或要写入文件的数据。

二、文件描述符

文件描述符(File Descriptor)是Linux和UNIX系统编程中的一个重要概念,它是一个用于标识打开文件或其他输入/输出资源的非负整数。文件描述符允许程序通过一个抽象的数字来引用文件和其他输入输出资源,而不是直接使用文件名或设备名。

2.1. 唯一性

在进程的生命周期内,每个打开的文件或设备都会分配一个唯一的文件描述符。这些描述符是从3开始分配的,因为0、1、2已经被系统预留给标准输入(stdin)、标准输出(stdout)和标准错误(stderr)了。

例如,如果进程首先打开一个文件,它将被分配文件描述符3;接着打开第二个文件,则分配文件描述符4,以此类推。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>int main() {int fd1 = open("file1.txt", O_RDONLY);int fd2 = open("file2.txt", O_RDONLY);int fd3 = open("file3.txt", O_RDONLY);if (fd1 == -1 || fd2 == -1 || fd3 == -1) {perror("open");return 1;}printf("File descriptors: file1.txt = %d, file2.txt = %d, file3.txt = %d\n", fd1, fd2, fd3);close(fd1);close(fd2);close(fd3);return 0;
}

我们打开了三个文件,并打印了它们的文件描述符。通过运行,可以观察到文件描述符是从3开始递增分配的(假设0、1、2没有被占用或重定向)。 

2.2. 抽象性

文件描述符提供了一种抽象机制,使得程序可以通过简单的数字来引用复杂的I/O资源。这种抽象性简化了编程模型,因为程序员不需要关心底层的设备或文件实现细节。

文件描述符的这种抽象性也支持了重定向和管道等高级I/O操作。例如,可以将一个进程的标准输出重定向到一个文件,或者将一个进程的输出作为另一个进程的输入,这些操作都可以通过操作文件描述符来实现。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main() {int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);if (fd == -1) {perror("open");return 1;}const char *text = "Hello, file descriptor!\n";ssize_t bytes_written = write(fd, text, strlen(text));if (bytes_written == -1) {perror("write");close(fd);return 1;}close(fd);return 0;
}

打开(或创建)了一个文件,并使用write函数通过文件描述符向其中写入数据。文件描述符在这里作为I/O操作的抽象引用。 

2.3. 有限性

文件描述符的数量是有限的,这个限制通常由系统设置决定。在Linux系统中,可以使用ulimit -n命令来查看和设置当前shell进程的文件描述符限制。

默认情况下,这个限制可能比较低(如1024),但在现代系统中,这个限制通常可以被提高。提高文件描述符限制对于需要打开大量文件的服务器程序来说是非常重要的。

需要注意的是,虽然系统允许提高文件描述符限制,但这也受到系统资源(如内存)的限制。打开过多的文件可能会导致系统资源耗尽,从而影响系统的稳定性和性能。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>int main() {struct rlimit rl;// 获取当前文件描述符限制if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {perror("getrlimit");exit(EXIT_FAILURE);}printf("Current file descriptor limit: soft = %lld, hard = %lld\n",(long long)rl.rlim_cur, (long long)rl.rlim_max);// 尝试提高软限制(在硬限制范围内)rl.rlim_cur = rl.rlim_max; // 或者设置为一个较小的值,但不超过硬限制if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {perror("setrlimit");exit(EXIT_FAILURE);}// 再次获取限制以确认更改if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {perror("getrlimit");exit(EXIT_FAILURE);}printf("New file descriptor limit: soft = %lld, hard = %lld\n",(long long)rl.rlim_cur, (long long)rl.rlim_max);return 0;
}

首先获取了当前的文件描述符限制(软限制和硬限制),然后尝试将软限制提高到硬限制的值。请注意,硬限制是由系统管理员设置的,普通用户可能无法更改它。如果尝试设置一个超过硬限制的值,setrlimit调用将失败。 

三、文件操作函数

在Linux系统中,文件操作主要涉及到以下几个函数:

  • open()函数:用于打开文件。其原型为int open(const char *pathname, int flags, mode_t mode)。其中,pathname是文件名或路径,flags用于指定文件的打开模式(如只读、只写、读写等),mode用于设置文件权限(当创建新文件时)。
  • read()函数:用于从文件中读取数据。其原型为ssize_t read(int fd, void *buf, size_t count)。其中,fd是文件描述符,buf是指向存储读取数据的缓冲区的指针,count是要读取的字节数。
  • write()函数:用于向文件中写入数据。其原型为ssize_t write(int fd, const void *buf, size_t count)。参数含义与read()函数类似。
  • close()函数:用于关闭文件。其原型为int close(int fd)。其中,fd是文件描述符。
  • lseek()函数:用于移动文件指针。其原型为off_t lseek(int fd, off_t offset, int whence)。其中,fd是文件描述符,offset是偏移量,whence用于指定偏移的基准位置(如文件开头、当前位置、文件末尾等)。
  • creat()函数:用于创建文件。其原型为int creat(const char *pathname, mode_t mode)。其中,pathname是文件名或路径,mode用于设置文件权限。不过,在现代Linux系统中,creat()函数已经被open()函数所取代,因为open()函数提供了更丰富的功能。

四、标准文件I/O函数

除了上述低级的文件操作函数外,Linux还提供了一套标准的文件I/O函数,这些函数封装了复杂的底层细节,便于用户进行日常文件操作。标准文件I/O函数主要包括:

  • fopen()函数:用于打开文件。其原型为FILE *fopen(const char *filename, const char *mode)
  • fclose()函数:用于关闭文件。其原型为int fclose(FILE *stream)
  • fread()函数:用于从文件中读取数据。其原型为size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  • fwrite()函数:用于向文件中写入数据。其原型为size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  • fgets()函数:用于从文件中读取一行字符。其原型为char *fgets(char *str, int n, FILE *stream)
  • fputs()函数:用于向文件中写入字符串。其原型为int fputs(const char *str, FILE *stream)

五、文件执行权限

在Linux系统中,文件执行权限是控制用户可以对文件执行哪些操作的重要机制。正确设置文件权限对于系统的安全性至关重要

5.1. 权限类型

Linux文件权限主要分为三类:

  • 读权限(r):允许用户读取文件内容或列出目录内容。
  • 写权限(w):允许用户修改文件内容或在目录中创建、删除文件。
  • 执行权限(x):允许用户执行文件(如果文件是可执行文件)或进入目录。

5.2. 权限分配对象

这些权限可以被分配给以下三个对象:

  • 文件所有者(owner):文件的创建者或拥有者,对文件具有最高的控制权限。
  • 文件所属组(group):文件所属的用户组,组内的所有用户共享这些权限。
  • 其他用户(others):既不是文件所有者,也不属于文件所属组的用户。

5.3. 权限表示方法

Linux系统提供两种表示文件权限的方法:数字表示法和符号表示法。

  • 数字表示法

    • 读权限(r)= 4
    • 写权限(w)= 2
    • 执行权限(x)= 1
    • 将这三种权限的数字相加,就可以得到每个用户类别的权限值。例如,7表示读、写和执行权限(4+2+1),5表示读和执行权限(4+1)。
  • 符号表示法:使用字符来表示权限,通常与用户名、组名一起显示在ls -l命令的输出中。例如,-rwxr-xr--表示一个普通文件,所有者有读、写和执行权限,组用户有读和执行权限,其他用户只有读权限。

5.4. 权限设置命令

在Linux中,可以使用chmod命令来设置或修改文件权限。

  • 符号表示法设置权限

    • chmod u+x 文件名:给文件的所有者添加执行权限。
    • chmod g+w,o+r 文件名:给用户组增加写权限,给其他用户增加读权限。
    • chmod a=r 文件名:将文件的权限设置为所有人仅具有读权限。
  • 数字表示法设置权限

    • chmod 755 文件名:设置文件所有者为读写执行权限(7),用户组和其他用户为读执行权限(5)。
    • chmod 644 文件名:设置文件所有者为读写权限(6),用户组和其他用户为读权限(4)。

5.5. 权限设置的重要性

正确设置文件权限对于Linux系统的安全性至关重要。通过合理设置文件权限,可以控制不同用户对文件和目录的访问和操作,防止未经授权的访问和修改,从而保护系统资源的安全。

5.6. 实例说明

假设有一个名为script.sh的Shell脚本文件,需要给其所有者添加执行权限,以便能够执行该脚本。可以使用以下命令:

chmod u+x script.sh

或者,也可以使用数字表示法来设置权限: 

chmod 755 script.sh

这样,script.sh文件的所有者将拥有读、写和执行权限,而用户组和其他用户将拥有读和执行权限(虽然对于脚本文件来说,写权限通常不是必需的,但这里为了演示目的而包含)。

六、设备文件读写

在嵌入式Linux系统中,设备文件是一种将硬件设备抽象为普通文件的机制。这种抽象使得用户空间程序可以通过标准的文件I/O操作(如openreadwriteclose等)来与硬件设备进行交互。设备文件通常位于/dev目录下,并且根据其特性被分类为字符设备或块设备。

6.1. 设备文件类型

  • 字符设备:字符设备以字符为单位进行数据传输,如串口(UART)、键盘、鼠标等。对字符设备的读写操作通常不会涉及缓存,因为数据是即时处理的。
  • 块设备:块设备以块(通常是512字节或更大)为单位进行数据传输,如硬盘、SD卡等。对块设备的读写操作可能会涉及缓存,以提高性能。

6.2. 设备文件的命名

  • 设备文件通常以设备类型加上设备编号的形式命名。例如,/dev/ttyS0可能表示第一个串口设备,而/dev/sda1可能表示第一个SCSI硬盘的第一个分区。

6.3. 设备文件的读写操作

在嵌入式编程中,对设备文件的读写操作通常涉及以下步骤。

  • 打开设备文件:使用open函数打开设备文件,指定操作模式(如读、写或读写)。
  • 配置设备(如果需要):对于某些设备,可能需要通过ioctl函数发送控制命令来配置设备参数。
  • 读写操作
    • 使用read函数从设备读取数据。
    • 使用write函数向设备写入数据。
  • 处理错误:检查每个系统调用的返回值,以处理可能的错误情况。
  1. 关闭设备文件:使用close函数关闭设备文件,释放资源。

6.4. 示例:串口通信

以下是一个简单的示例,展示如何通过读写串口设备文件来进行通信:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>int main() {int fd;struct termios options;// 打开串口设备文件fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);if (fd < 0) {perror("open");exit(EXIT_FAILURE);}// 配置串口参数tcgetattr(fd, &options);cfsetispeed(&options, B9600); // 设置输入波特率cfsetospeed(&options, B9600); // 设置输出波特率options.c_cflag |= (CLOCAL | CREAD); // 启用接收器,忽略调制解调器控制线options.c_cflag &= ~PARENB; // 无奇偶校验options.c_cflag &= ~CSTOPB; // 一个停止位options.c_cflag &= ~CSIZE;options.c_cflag |= CS8; // 8个数据位tcsetattr(fd, TCSANOW, &options);// 写入数据到串口const char *msg = "Hello, UART!\n";write(fd, msg, strlen(msg));// 从串口读取数据(这里只是示例,实际应用中可能需要循环读取)char buf[256];int n = read(fd, buf, sizeof(buf) - 1);if (n > 0) {buf[n] = '\0'; // 确保字符串以null结尾printf("Received: %s", buf);} else if (n < 0) {perror("read");}// 关闭串口设备文件close(fd);return 0;
}

首先打开了/dev/ttyS0设备文件,配置了串口参数(如波特率、数据位、停止位等),然后向串口写入了数据,并从串口读取了数据(虽然在实际应用中,读取操作通常是在一个循环中进行的)。最后,关闭了设备文件。

综上所述,嵌入式Linux应用开发中的文件I/O基础编程涉及到文件描述符、文件操作函数、标准文件I/O函数以及文件执行权限等多个方面。掌握这些基础知识对于进行嵌入式Linux应用开发至关重要。

相关文章:

【嵌入式Linux应用开发基础】文件I/O基础编程

目录 一、文件I/O简介 二、文件描述符 2.1. 唯一性 2.2. 抽象性 2.3. 有限性 三、文件操作函数 四、标准文件I/O函数 五、文件执行权限 5.1. 权限类型 5.2. 权限分配对象 5.3. 权限表示方法 5.4. 权限设置命令 5.5. 权限设置的重要性 5.6. 实例说明 六、设备文件…...

Java 反射机制的安全隐患与防范措施:在框架开发与代码审计中的应用

前言 在 Java 编程的广阔领域中&#xff0c;反射机制堪称一把神奇且强大的钥匙&#xff0c;它为开发者打开了通往动态编程的全新大门。借助反射&#xff0c;Java 程序获得了在运行时自我审视和操作的独特能力&#xff0c;极大地增强了代码的灵活性与适应性。 简单来讲&#x…...

【JS】实现一个hexo插件并发布

hexo插件生成 在你的 hexo blog 目录&#xff0c;找到 node_modules. 新建一个文件夹。然后执行 npm init npm 会引导你生成 package.json 这是你的包的描述文件。需要注意的是&#xff0c;所有的 hexo 插件必须以 hexo - 开头&#xff0c;否则 hexo 不会加载。 如果hexo g中没…...

【Java 面试 八股文】MySQL 篇

MySQL 篇 1. MySQL中&#xff0c;如何定位慢查询&#xff1f;2. 那这个SQL语句执行很慢&#xff0c;如何分析呢&#xff1f;3. 了解过索引吗&#xff1f;&#xff08;什么是索引&#xff09;4. 索引的底层数据结构了解过吗&#xff1f;5. B树和B树的区别是什么呢&#xff1f;6.…...

ES6 Proxy 用法总结以及 Object.defineProperty用法区别

Proxy 是 ES6 引入的一种强大的拦截机制&#xff0c;用于定义对象的基本操作&#xff08;如读取、赋值、删除等&#xff09;的自定义行为。相较于 Object.defineProperty&#xff0c;Proxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法 const proxy new Proxy(target, hand…...

vue中使用高德地图自定义掩膜背景结合threejs

技术架构 vue3高德地图2.0threejs 代码步骤 这里我们就用合肥市为主要的地区&#xff0c;将其他地区扣除&#xff0c;首先使用高德的webapi的DistrictSearch功能&#xff0c;使用该功能之前记得检查一下初始化的时候是否添加到plugins中&#xff0c;然后搜索合肥市的行政数据…...

tomcat如何配置保存7天滚动日志

在 Tomcat 中&#xff0c;logging.properties 文件是用于配置 Java 日志框架&#xff08;java.util.logging&#xff09;的。若要实现 catalina.out 日志保存 7 天&#xff0c;且每天的日志文件名带有时间戳&#xff0c;可以按以下步骤进行配置&#xff1a; 1. 备份原配置 在修…...

ffmpeg -pix_fmts

1. ffmpeg -pix_fmts -loglevel quiet 显示ffmpeg支持的像素格式 2. 输出 选取部分输出结果 Pixel formats: I.... Supported Input format for conversion .O... Supported Output format for conversion ..H.. Hardware accelerated format ...P. Paletted format ..…...

Python----PyQt开发(PyQt高级:图像显示,定时器,进度条)

一、图像显示 1.1、增加图标 1.直接创建setWindowIcon(QIcon(灯泡.jpg)) import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton from PyQt5.QtGui import QIconclass MainWindow(QMainWindow):def __init__(self):super(MainWindow, self).__init_…...

Tomcat添加到Windows系统服务中,服务名称带空格

要将Tomcat添加到Windows系统服务中&#xff0c;可以通过Tomcat安装目录中“\bin\service.bat”来完成&#xff0c;如果目录中没有service.bat&#xff0c;则需要使用其它方法。 打到CMD命令行窗口&#xff0c;通过cd命令跳转到Tomcat安装目录的“\bin\”目录&#xff0c;然后执…...

2025.2.10 每日学习记录3:技术报告只差相关工作+补实验

0.近期主任务线 1.完成小论文准备 目标是3月份完成实验点1的全部实验和论文。 2.准备教资笔试 打算留个十多天左右&#xff0c;一次性备考笔试的三个科目 1.实习申请技术准备&#xff1a;微调、Agent、RAG 据央视财经&#xff0c;数据显示&#xff0c;截至2024年12月…...

普通用户授权docker使用权限

1、检查docker用户组 sudo cat /etc/group |grep docker 若显示&#xff1a;docker:x:999: # 表示存在否则创建docker用户组&#xff1a; sudo groupadd docker2、查看 /var/run/docker.sock 的属性 ll /var/run/docker.sock 显示&#xff1a; srw-rw---- 1 root root 0 1月…...

微生物学术语和定义 | 微生物学词汇表

​ 微生物学作为一门研究微生物及其与环境、宿主和其他生物相互作用的科学&#xff0c;涵盖了广泛的学科领域和专业术语。然而&#xff0c;由于微生物学的快速发展和跨学科融合&#xff0c;许多术语的定义和使用在不同领域中可能存在差异甚至混淆。 随着新冠疫情的全球蔓延&am…...

Java集合List详解(带脑图)

允许重复元素&#xff0c;有序。常见的实现类有 ArrayList、LinkedList、Vector。 ArrayList ArrayList 是在 Java 编程中常用的集合类之一&#xff0c;它提供了便捷的数组操作&#xff0c;并在动态性、灵活性和性能方面取得了平衡。如果需要频繁在中间插入和删除元素&#xf…...

后盾人JS -- 异步编程,宏任务与微任务

异步加载图片体验JS任务操作 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…...

Go语言的内存分配原理

Go语言的内存分配原理 Go语言的内存管理分为两个主要区域&#xff1a;栈&#xff08;Stack&#xff09; 和 堆&#xff08;Heap&#xff09;。理解这两个区域的工作原理&#xff0c;可以帮助你写出更高效的代码&#xff0c;并避免一些常见的性能问题。 1. 栈&#xff08;Stac…...

分层解耦-ioc引入

内聚: 软件中各个功能模块内部的功能联系。 耦合: 衡量软件中各个层/模块之间的依赖、关联的程度。 软件设计原则: 高内聚低耦合。...

【知识科普】CPU,GPN,NPU知识普及

CPU,GPU,NPU CPU、GPU、NPU 详解1. CPU&#xff08;中央处理器&#xff09;2. GPU&#xff08;图形处理器&#xff09;3. NPU&#xff08;神经网络处理器&#xff09; **三者的核心区别****协同工作示例****总结** CPU、GPU、NPU 详解 1. CPU&#xff08;中央处理器&#xff0…...

【管理与实物】1.1.1 建筑物分类与构成

1.1.1 建筑物分类与构成 建筑物的分类建筑物的构成 一、课前学习建议 民用建筑的分类&#xff1a;根据《民用建筑设计统一标准》GB50352-2019 划分可划分为单层或多层民用建筑、高层民用建筑、超高层民用建筑&#xff1b;根据《建筑设计防火规范》GB50016-2014&#xff08;2…...

CentOS虚机在线扩容系统盘数据盘

最近在制作Openstack下的镜像&#xff0c;用户需要CentOS6以及CentOS7的虚机镜像&#xff0c;遇到了些关于系统盘以及数据盘在线扩容的问题&#xff0c;故此整理一下。 ​ 传统我们想对磁盘在线热扩容&#xff0c;必然会想到LVM逻辑卷。如果没有LVM逻辑卷的情况下&#xff0c;…...

使用Kickstart配置文件封装操作系统实现Linux的自动化安装

使用Kickstart配置文件封装操作系统实现Linux的自动化安装 创建ks.cfg配置文件 可以使用已经安装完成的Linux操作系统中的/root目录下的anaconda.cfg配置文件 注意&#xff0c;配置文件会因为kickstart的版本兼容性的问题导致无法安装报错需要在实际使用过程中删除某些参数 …...

如何利用DeepSeek开源模型打造OA系统专属AI助手

利用DeepSeek开源模型打造OA系统专属AI助手&#xff0c;可以显著提升办公效率&#xff0c;增强信息检索和管理能力。 注册与登录DeepSeek平台 访问DeepSeek官网 访问DeepSeek的官方网站DeepSeek。使用电子邮件或手机号码注册账号并登录。 获取API Key 登录DeepSeek平台&am…...

【20250211】栈与队列:1047.删除字符串中的所有相邻重复项

#方法一&#xff1a;使用栈 # class Solution: # def removeDuplicates(self, s): # res [] # for char in s: # #真和消消乐一样&#xff0c;栈外来一个数据&#xff0c;如果和栈顶数据相同&#xff0c;则不仅不入栈&#xff0c;还把栈顶数据…...

使用Hexo部署NexT主体网站

一.使用git提交文件 参考&#xff1a; 从零开始搭建个人博客&#xff08;超详细&#xff09; - 知乎 致谢&#xff01; 第一种&#xff1a;本地没有 git 仓库 直接将远程仓库 clone 到本地&#xff1b;将文件添加并 commit 到本地仓库&#xff1b;将本地仓库的内容push到远程仓…...

uni getLocation 公众号h5获取定位坐标没有返回

先看代码 //获取经纬度getLocation() {console.log("111")uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&#xff1a; res.longitude);console.log(当前位置的纬度&#xff1a; res.latitude);},fail: function(err) {conso…...

C语言基本概念————讨论sqrt()和pow()函数与整数的关系

本文来源&#xff1a;C语言基本概念——讨论sqrt()和pow()函数与整数的关系. C语言基本概念——sqrt和pow函数与整数的关系 1. 使用sqrt()是否可以得到完全平方数的精确的整数平方根1.1 完全平方数的计算结果是否精确&#xff1f;1.2 为什么不会出现误差&#xff08;如 1.99999…...

【时时三省】(C语言基础)什么是算法

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 一个程序主要包括以下两方面的信息&#xff1a; &#xff08;1&#xff09;对数据的描述。在程序中&#xff0c;要指定用到哪些数据&#xff0c;以及这些数据的类型和数据组织形式。这就是数…...

Spring Boot 中加载多个 YAML 配置文件

在 Spring Boot 中加载多个 YAML 配置文件是一个常见的需求&#xff0c;通常用于将配置信息分离到多个文件中以便于管理和维护。Spring Boot 提供了灵活的方式来加载多个 YAML 配置文件。 以下是一些方法和步骤&#xff0c;用于在 Spring Boot 应用中加载多个 YAML 配置文件&a…...

IPoIB模块初始化过程详解

在现代网络环境中,InfiniBand over IP (IPoIB) 作为一种高性能的网络技术,被广泛应用于数据中心和高性能计算领域。为了确保其稳定性和高效性,Linux内核中的IPoIB模块在加载时需要进行一系列复杂的初始化操作。本文将基于一系列技术对话内容,详细介绍IPoIB模块的初始化流程…...

C语言——排序(冒泡,选择,插入)

基本概念 排序是对数据进行处理的常见操作&#xff0c;即将数据按某字段规律排列。字段是数据节点的一个属性&#xff0c;比如学生信息中的学号、分数等&#xff0c;可针对这些字段进行排序。同时&#xff0c;排序算法有稳定性之分&#xff0c;若两个待排序字段一致的数据在排序…...