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

【嵌入式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. 实例说明 六、设备文件…...

【StableDiffusion容器化部署】分步指南

使用Docker部署和管理Stable Diffusion环境可以有效解决依赖冲突、环境隔离和可移植性问题。以下是分步指南和相关技术细节&#xff1a; 1. 基础环境准备 1.1 安装Docker和GPU支持 安装Docker Engine&#xff1a;参考官方文档配置NVIDIA Container Toolkit&#xff1a;# 安装…...

2.11 sqlite3数据库【数据库的相关操作指令、函数】

练习&#xff1a; 将 epoll 服务器 客户端拿来用 客户端&#xff1a;写一个界面&#xff0c;里面有注册登录 服务器&#xff1a;处理注册和登录逻辑&#xff0c;注册的话将注册的账号密码写入数据库&#xff0c;登录的话查询数据库中是否存在账号&#xff0c;并验证密码是否正确…...

安装 Ollama 需要哪些步骤?(windows+mac+linux+二进制+Docker)

安装 Ollama 的步骤根据操作系统不同会有所差异,以下是针对不同操作系统的详细安装指南: Windows 系统 下载安装包:访问 Ollama 官方下载页面,下载适用于 Windows 的安装程序 OllamaSetup.exe。运行安装程序:双击下载的安装包,按照提示完成安装。默认安装路径为 C:\User…...

【力扣】148.排序链表

AC截图 题目 思路 基本情况处理&#xff1a; 如果链表为空 (head NULL) 或者链表仅有一个节点 (head->next NULL)&#xff0c;则链表已经是有序的&#xff0c;直接返回头节点 head。 分割链表&#xff1a; 使用快慢指针法找到链表的中间节点。slow 指针每次前进一格&…...

Springboot框架扩展功能的使用

Spring Boot 提供了许多扩展点&#xff0c;允许开发者在应用程序的生命周期中插入自定义逻辑。这些扩展点可以帮助你更好地控制应用程序的行为&#xff0c;例如在启动时初始化数据、在关闭时释放资源、或者自定义配置加载逻辑。以下是 Spring Boot 中常见的扩展点&#xff1a; …...

绿虫储能仿真软件解决储能项目中的哪些痛点

痛点一&#xff1a;储能方案定制难 如何根据不同用户的需求&#xff0c;制定科学合理的储能方案&#xff0c;一直是行业内的一大难题。每个用户的用电情况、场地条件、预算等都存在差异&#xff0c;想要实现 “千人千面” 的专属方案设计谈何容易。 绿虫储能仿真设计软件凭借…...

保姆级教程Docker部署Zookeeper镜像

目录 一、安装Docker及可视化工具 二、创建Zookeeper网络 三、镜像选择 四、单节点部署 1、创建挂载目录 2、命令运行容器 3、Compose运行容器 4、查看运行状态 5、验证是否正常运行 一、安装Docker及可视化工具 Docker及可视化工具的安装可参考&#xff1a;Ubuntu上…...

【leetcode】滑动窗口刷题总结

滑动窗口算法技巧主要用来解决子数组问题&#xff0c;比如让你寻找符合某个条件的最长/最短子数组或者子串。对于某些题目&#xff0c;并不需要穷举所有子串&#xff0c;就能找到题目想要的答案。滑动窗口就是这种场景下的一套算法模板&#xff0c;帮你对穷举过程进行剪枝优化&…...

【MySQL】通过shell脚本一键同步MySQL数据库结构和数据到指定库中

通过shell脚本对数据库进行覆盖式备份/迁移&#xff0c;简单方便&#xff0c;适合需要快速同步某个库结构和数据到目标库的场景。 通过AI调试了好些次得到能用的脚本&#xff0c;本文主要是做一个对该脚本的记录| 安装依赖 # 安装进度条库 sudo apt install pv注&#xff1a;如…...

C# COM 组件在.NET 平台上的编程介绍

.NET学习资料 .NET学习资料 .NET学习资料 一、COM 组件简介 COM&#xff08;Component Object Model&#xff09;即组件对象模型&#xff0c;是一种微软提出的软件组件技术&#xff0c;它允许不同的软件模块在二进制层面进行交互。COM 组件可以用多种编程语言开发&#xff0…...

数据结构与算法:动态规划dp:背包问题:理论基础(状态压缩/滚动数组)和相关力扣题(416. 分割等和子集、1049.最后一块石头的重量Ⅱ、494.目标和)

背包问题 01背包理论基础 对于01背包问题&#xff0c;物品下标为0到i&#xff0c;对应的重量为weight[0]到weight[i]&#xff0c;价值为value[0]到value[i]&#xff0c;每个物品只可以取或不取&#xff0c;背包最大容量为j的场景。 常见的状态转移方程如下&#xff1a; dp[i…...

【MySQL例题】我在广州学Mysql 系列——有关数据备份与还原的示例

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周二&#xff0c;明天就是元宵节了呀&#xff01;&#xff01;&#x1f606; 俗话说“众里寻他千百度。蓦然回首&#xff0c;那人却在&#xff0c;灯火阑珊处。” 本文主要对数据库备份与还原的知识点例题学习~~ 前情回顾&…...

【Git】完美解决git push报错403

remote: Permission to xx.git denied to xx. fatal: unable to access https://github.com/xx/xx.git/: The requested URL returned error: 403出现这个就是因为你的&#xff08;personal access tokens &#xff09;PAT过期了 删掉旧的token 生成一个新的 mac系统 在mac的…...

2021 年 9 月青少年软编等考 C 语言五级真题解析

目录 T1. 问题求解思路分析T2. 抓牛思路分析T3. 交易市场思路分析T4. 泳池思路分析T1. 问题求解 给定一个正整数 N N N,求最小的 M M M 满足比 N N N 大且 M M M 与 N N N 的二进制表示中有相同数目的 1 1 1。 举个例子,假如给定 N N N 为 78 78 78,二进制表示为 …...

玩转适配器模式

文章目录 解决方案现实的举例适用场景实现方式适配器模式优缺点优点:缺点:适配器模式可比上一篇的工厂模式好理解多了,工厂模式要具有抽象的思维。这个适配器模式,正如字面意思,就是要去适配某一件物品。 假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格…...

Batch Normalization (BN) 和 Synchronized Batch Normalization (SyncBN) 的区别

Batch Normalization 和 Synchronized Batch Normalization 的区别 Batch Normalization (BN) 和 Synchronized Batch Normalization (SyncBN) 的区别1. BN&#xff08;Batch Normalization&#xff09;2. SyncBN&#xff08;Synchronized Batch Normalization&#xff09;3. 选…...

MySQL主从同步

目录 一、MySQL主从同步 1、基于binlog的主从同步 2、基于gtid的主从同步配置 二、MySQL 主从读写分离实现方案 2.1 ProxySQL实现mysql8主从同步读写分离 1、ProxySQL基本介绍 2、ProxySQL结构 2、实验环境 3、实现数据库主从复制 4、安装ProxySQL 5、配置ProxySQL …...

CCFCSP认证考试 ——202403-1 词频统计

题目&#xff1a; 在学习了文本处理后&#xff0c;小 P 对英语书中的 n 篇文章进行了初步整理。 具体来说&#xff0c;小 P 将所有的英文单词都转化为了整数编号。假设这 n 篇文章中共出现了 m 个不同的单词&#xff0c;则把它们从 1 到 m 进行编号。 这样&#xff0c;每篇文章…...

关于“i18n“在vue中的使用

关于"i18n"在vue中的使用 <!-- vue2中 --> <template><div>{{ $t("This campaign has expired.") }}}}</div> </template> <script> export default {created() {this.onLoading();},methods: {onLoading () {this.$…...

MATLAB中count函数用法

目录 语法 说明 示例 对出现次数计数 使用模式对数字和字母进行计数 多个子字符串的所有出现次数 忽略大小写 对字符向量中的子字符串进行计数 count函数的功能是计算字符串中模式的出现次数。 语法 A count(str,pat) A count(str,pat,IgnoreCase,true) 说明 A c…...

Spring中的@Component和@Bean有什么区别?

在Spring框架中&#xff0c;Component和Bean都用于定义Bean&#xff0c;但它们的使用场景和方式有所不同。 ### 1. Component - **作用范围**&#xff1a;Component是一个类级别的注解&#xff0c;通常用于标记一个类为Spring的组件。Spring会自动扫描并注册这些类为Bean。 -…...

泛化、选择、分化

泛化是指记忆联系的“发散”&#xff0c;泛化兴奋的基础是模糊兴奋。记忆联系的“发散”有以下几种种情况&#xff1a; 1、联络区的一原始记忆柱群&#xff08;A1&#xff09;具有直接或间接与其它任意联络区的任意原始记忆柱群建立记忆联系的潜力。也就是说任何两个对象&…...

剖析 C++ 模拟算法:数据结构、随机数生成与模型验证

模拟算法 (Simulation Algorithms) 是一种通过计算机程序来模拟现实世界或系统行为的算法。它不依赖于特定的数学公式或优化技术&#xff0c;而是直接按照系统的规则和逻辑进行步骤一步地模拟。 模拟算法的复杂度和效率取决于模拟系统的复杂程度和模拟的精度要求。 在 C 中&…...

51单片机俄罗斯方块整行消除函数

/************************************************************************************************************** * 名称&#xff1a;flash * 功能&#xff1a;行清除动画 * 参数&#xff1a;NULL * 返回&#xff1a;NULL * 备注&#xff1a; * 采用非阻塞延时&#xff0…...

IDEA升级出现问题Failed to prepare an update Temp directory inside installation

IDEA升级出现问题"Failed to prepare an update Temp directory inside installation…" 问题来源&#xff1a; 之前修改了IDEA的默认配置文件路径&#xff0c;然后升级新版本时就无法升级&#xff0c;提示"Failed to prepare an update Temp directory insid…...

Windows系统下设置Vivado默认版本:让工程文件按需打开

在FPGA开发过程中&#xff0c;我们常常需要在一台电脑上安装多个不同版本的Vivado软件&#xff0c;以满足不同项目的需求。然而&#xff0c;当双击打开一个Vivado工程文件&#xff08;.xpr&#xff09;时&#xff0c;系统默认会调用一个固定的版本&#xff0c;这可能并不是我们…...

CSS3+动画

浏览器内核以及其前缀 css标准中各个属性都要经历从草案到推荐的过程&#xff0c;css3中的属性进展都不一样&#xff0c;浏览器厂商在标准尚未明确的情况下提前支持会有风险&#xff0c;浏览器厂商对新属性的支持情况也不同&#xff0c;所有会加厂商前缀加以区分。如果某个属性…...

Kotlin 2.1.0 入门教程(十一)for、while、return、break、continue

for 循环 for 循环会遍历任何提供迭代器的对象。 for (item in collection) print(item)for (int: Int in ints) {println(int) }for 循环会遍历任何提供迭代器的对象&#xff0c;这意味着该对象必须满足以下条件&#xff1a; 具有一个成员函数或扩展函数 iterator()&#xf…...

深度探索DeepSeek:成本效益之辩与市场展望

摘要 DeepMind的CEO对DeepSeek的成本效益提出质疑&#xff0c;认为其成本被过度炒作。他指出&#xff0c;DeepSeek所使用的技术大多源自谷歌和DeepMind。然而&#xff0c;分析机构SemiAnalysis强调&#xff0c;DeepSeek的优势在于其成本与能力的卓越组合。尽管目前DeepSeek的成…...

DeepSeek投喂数据(训练AI)

1、拉取nomic-embed-text 打开命令行&#xff0c;运行&#xff1a;ollama pull nomic-embed-text 这里需要先安装ollama &#xff0c;不过大家应该在本地部署模型时已经安装了 拉取成功就行了&#xff0c;后续在配置AnythingLLM时用到 2、下载 AnythingLLM 地址&#xff1a…...

Docker 安装与配置 Nginx

摘要 1、本文全面介绍了如何在 Docker 环境中安装和配置 Nginx 容器。 2、文中详细解释了如何设置 HTTPS 安全连接及配置 Nginx 以实现前后端分离的代理服务。 2、同时&#xff0c;探讨了通过 IP 和域名两种方式访问 Nginx 服务的具体配置方法 3、此外&#xff0c;文章还涵…...

常用电路(过压保护、电流/电压采集)

过压保护电路 输入电压使用电源&#xff08;36V&#xff09;或者typec&#xff08;20V&#xff09;&#xff0c;需要过压保护电路处理输入再连接到CH224K&#xff0c;保证输入不高于最大获取电压20V MOS管导通条件为栅源极有压差&#xff0c;一般为5-10V 三极管导通条件为基极…...

12.Python模块:模块中的__all__、模块制作、打包模块、模块安装与使用

在 Python 中&#xff0c;模块是一个包含 Python 代码的文件。模块可以包含函数、类和变量&#xff0c;也可以包括可执行的代码。Python提供了一套强大的模块系统&#xff0c;支持模块的制作、打包、安装和使用。接下来&#xff0c;我们将详细介绍 __all__、模块制作、打包模块…...

Socket通信端口绑定的逻辑实现

在实现网络通信时&#xff0c;一个 Socket 需要维护输入端与输出端的 IP 地址和端口号&#xff0c;同时也需要输入与输出字节缓冲区&#xff1a; 输入端与输出端的 IP 地址和端口号 作用 标识通信端点&#xff1a;IP 地址用于标识网络中的设备&#xff0c;端口号用于标识设备…...

在freertos中,中断优先级和任务优先级之间的关系和使用方法

中断优先级和任务优先级如何匹配&#xff1f;任务优先级不同任务之间该用多高的优先级&#xff1f;中断优先级不同中断中该用多高的优先级&#xff1f;中断优先级和任务优先级设置时&#xff0c;怎样设置可以让任务在调度时屏蔽中断&#xff1f;怎样设置可以让任务在调度时&…...

解锁摄影潜能:全面解析相机镜头的选择与使用逻辑

目录 一、镜头分类&#xff1a;从焦距到用途的底层逻辑 &#xff08;一&#xff09;按焦距和视角分类&#xff08;一级分类&#xff09; &#xff08;二&#xff09;按特殊用途分类&#xff08;一级分类&#xff09; 二、参数解码&#xff1a;超越 “光圈越大越好” 的思维定…...

java项目之直销模式下家具工厂自建网站源码(ssm+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的直销模式下家具工厂自建网站源码。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 直销模式下家具…...

CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测,光伏功率预测

代码地址&#xff1a;CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测&#xff0c;光伏功率预测 CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测 一、引言 1.1、研究背景和意义 光伏功率预测在现代电力系统中占有至关重要的地位。随着可再生能源…...

grid网格布局中实现父盒子比较大,子元素顶部对齐

css布局中使用grid布局&#xff0c;父盒子的高度是1000px&#xff0c;每个子元素高度是100px&#xff0c;现在有三个子元素&#xff0c;如何实现每行显示两个&#xff0c;并且子元素都顶部对齐&#xff1f;如图所示的效果。 grid布局文档&#xff1a;grid - CSS&#xff1a;层…...

P4814 [CCO 2014] 国王格鲁夫

题目描述 本题译自 CCO 2014 Day1 T2「King Gruff」 狼国王格鲁夫统治着一个居住着可爱的狐狸的繁荣、快乐的领地。对狐狸们来说,不幸的是,他根本不是一个好国王,而且还想让他们的生活过得很惨。 他的国家有 N 个城市,由 M 条路连接,第 i 条路可以让你从城市 Xi​ 走到…...

[QMT量化交易小白入门]-二十二、deepseek+cline+vscode,让小白使用miniQMT量化交易成为可能

本专栏主要是介绍QMT的基础用法&#xff0c;常见函数&#xff0c;写策略的方法&#xff0c;也会分享一些量化交易的思路&#xff0c;大概会写100篇左右。 QMT的相关资料较少&#xff0c;在使用过程中不断的摸索&#xff0c;遇到了一些问题&#xff0c;记录下来和大家一起沟通&a…...

吃瓜教程Day1笔记

主要内容&#xff1a; 1. 什么是机器学习以及 2. 机器学习的相关数学符号&#xff0c;为后续内容作铺垫&#xff0c;并未涉及复杂的算法理论&#xff0c; 因此阅读本章时只需耐心梳理清楚所有概念和数学符号即可。 3. “模型评估与选择” 是在模型产出以后进行的下游工作&…...

在 C# 中,处理 Excel 和 PDF 文件的库有很多。以下是一些比较常用的选择

读取 Excel 文件的库 NPOI 用途&#xff1a;可以读取和写入 .xls 和 .xlsx 文件。特点&#xff1a;无需安装 Microsoft Office&#xff0c;支持简单的 Excel 操作&#xff0c;如格式化、公式、图表等。 EPPlus 用途&#xff1a;主要用于 .xlsx 格式&#xff08;Excel 2007 及以…...

IntelliJ IDEA 安装与使用完全教程:从入门到精通

一、引言 在当今竞争激烈的软件开发领域&#xff0c;拥有一款强大且高效的集成开发环境&#xff08;IDE&#xff09;是开发者的致胜法宝。IntelliJ IDEA 作为 JetBrains 公司精心打造的一款明星 IDE&#xff0c;凭借其丰富多样的功能、智能精准的代码提示以及高效便捷的开发工…...

SkyWalking 10.1.0 实战:从零构建全链路监控,解锁微服务性能优化新境界

文章目录 前言一、集成SkyWalking二、SkyWalking使用三、SkyWalking性能剖析四、SkyWalking 告警推送4.1 配置告警规则4.2 配置告警通知地址4.3 下发告警信息4.4 测试告警4.5 慢SQL查询 总结 前言 在传统监控系统中&#xff0c;我们通过进程监控和日志分析来发现系统问题&…...

1. 构建grafana(版本V11.5.1)

一、grafana官网 https://grafana.com/ 二、grafana下载位置 进入官网后点击downloads&#xff08;根据自己的需求下载&#xff09; 三、grafana安装&#xff08;点击下载后其实官网都写了怎么安装&#xff09; 注&#xff1a;我用的Centos&#xff0c;就简略的写下我的操作步…...

STM32-知识

一、Cortex-M系列双指针 Cortex-M系列的MSP与PSP有一些重要的区别&#xff0c;双指针是为了保证OS的安全性和稳健性。本质上&#xff0c;区别于用户程序使用PSP&#xff0c;操作系统和异常事件单独使用一个MSP指针的目的&#xff0c;是为了保证栈数据不会被用户程序意外访问或…...

SearchBar组件的功能与用法

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"Material3中的IconButton"相关的内容&#xff0c;本章回中将介绍SearchBar组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…...

解决VsCode的 Vetur 插件has no default export Vetur问题

文章目录 前言1.问题2. 原因3. 解决其他 前言 提示&#xff1a; 1.问题 Cannot find module ‘ant-design-vue’. Did you mean to set the ‘moduleResolution’ option to ‘node’, or to add aliases to the ‘paths’ option? Module ‘“/xxx/xxx/xxx/xxx/xxx/src/vie…...