[Linux]文件描述符(万字详解)
[Linux]文件描述符
文章目录
- [Linux]文件描述符
- 文件系统接口
- open函数
- close函数
- write函数
- read函数
- 系统接口与编程语言库函数的关系
- 文件描述符
- 文件描述符的概念
- 文件数据交换的原理
- 理解“一切皆文件”
- 进程默认文件描述符
- 文件描述符和编程语言的关系
- 重定向
- 输出重定向
- 输入重定向
- 追加重定向
- 使用指令完成重定向
- 重定向系统调用
- C语言文件缓冲区
文件系统接口
在学习文件描述符前,首先要了解一下Linux系统常用的文件系统接口。
open函数
//open函数所在的头文件和函数声明
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
- open函数有两个接口,三个参数的接口是在两个参数的接口的基础上添加了控制创建文件的权限功能,更适合写文件时使用
- pathname参数 – 要打开的文件所在的路径
- flags参数 – 打开文件的方式
- mode参数 – 如果要创建文件,文件的权限
- 函数成功返回一个新的文件描述符,函数失败返回-1,错误码被设置。
其中flags参数采用位图结构来接收要操作文件的打开模式,位图结构在这里的作用是只使用一个参数就可以传入多个标志信息,位图结构的具体形式是将flags参数的这样一个32位的整形变量中的每一个比特位都看作为一个个体,每个比特位都代表一个标志信息,位图结构的示意图如下:
假设flags参数的倒数第一比特位表示是否清空文件,如果该比特位为1表示需要清空文件,如果为0则表示不需要清空文件。
为了测试open函数编写如下代码:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = open(LOG, O_WRONLY);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}return 0;
}
编译代码运行并查看结果:
由于当前路径下不存在log.txt文件,O_WRONLY
打开模式是以读的方式打开文件,因此open函数使用失败,从错误信息中也可以看到失败原因是文件不存在。
再编写如下代码测试open函数:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = open(LOG, O_WRONLY | O_CREAT);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}return 0;
编译代码运行并查看结果:
执行程序后,我们能够发现由于文件权限是存在问题的,因此文件名被高亮显式了,由于本次使用的是O_WRONLY | O_CREAT
模式打开 O_CREAT
模式是如果文件不存在就创建文件,但是由于没有设置权限,因此文件权限存在问题。
再编写如下代码测试open函数:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{umask(0);int fd = open(LOG, O_WRONLY | O_CREAT, 0666);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));return 0;
}
编译代码运行并查看结果:
三参数的open函数接口第三个接口提供了创建文件是设置文件权限的功能,另外本段代码中使用了umask
函数,设置了该进程所使用的umask值,保证所创建的文件权限是想获得的。
//umask函数所在的头文件和函数声明
#include <sys/types.h>
#include <sys/stat.h>mode_t umask(mode_t mask);
close函数
//close函数所在的头文件和函数声明
#include <unistd.h>int close(int fd);
- close函数关闭文件能够避免文件内容出现问题
- close函数要关闭对应文件要传入使用open函数打开该文件时的返回值(文件描述符)
- 成功返回0,失败返回-1并且设置错误码
编写如下代码测试close函数:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{umask(0);int fd = open(LOG, O_WRONLY | O_CREAT, 0666);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));close(fd);return 0;
}
编译代码运行并查看结果:
write函数
//write函数所在的头文件和函数声明
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
- write函数能够将数据写入相应的文件中
- fd参数 – 用open函数打开该文件时的返回值(文件描述符)
- buf参数 – 要写入文件的数据
- count参数 – 要写入到文件中的数据字节数
- 成功返回写入的数据字节数,失败返回-1并且设置错误码
编写如下代码测试write函数:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{umask(0);int fd = open(LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));const char* msg = "hello world\n";write(fd, msg, strlen(msg)); close(fd);return 0;
}
编译代码运行并查看结果:
说明:
O_TRUNC
模式是在打开文件时先清空文件- 向文件写入数据时不需要将
'\0'
写入,其作用是在语言上表示字符串的结尾,在文件中不需要。
再编写如下代码测试write函数:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{umask(0);int fd = open(LOG, O_WRONLY | O_CREAT | O_APPEND, 0666);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));const char* msg = "hello world i love you\n";write(fd, msg, strlen(msg));close(fd);return 0;
}
编译代码运行并查看结果:
说明: O_APPEND
模式是采用追加的方式,需要和O_WRONLY
模式配合使用才能实现追加写入。
read函数
//read函数所在的头文件和函数声明
#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);
- read函数能够读取文件中的数据
- fd参数 – 要读取的文件的文件描述符
- buf参数 – 接收文件中数据的字符串变量地址
- count参数 – buf能接收的最大数据量,单位为字节
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = open(LOG, O_RDONLY);if (fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));exit(1);}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));char buffer[256];ssize_t n = read(fd, buffer, sizeof(buffer)-1);if (n > 0){buffer[n] = '\0';}printf("buffer: %s", buffer);close(fd);return 0;
}
编译代码运行并查看结果:
说明:
O_RDONLY
模式是以读取的方式打开文件- 用于接收read函数读取到的数据的字符串要在末尾预留一个元素存储
'\0'
系统接口与编程语言库函数的关系
由于计算机的体系结构中,操作系统是对上向用户提供服务,向下管理硬件的部分,并且文件的操作是会涉及到硬件的使用,导致编程语言语言库函数中的文件操作一定是对系统接口的封装,无论任何编程语言都是如此,因此无论何种编程语言其文件操作的本质都是相同的。计算机体系结构示意图如下:
文件描述符
文件描述符的概念
在学习文件描述符前要知道,观察Linux操作系统的文件系统接口,能够看出文件操作和文件描述符强相关,open函数的返回值,close函数、write函数、read函数的参数都是文件描述符。
首先,进行文件操作时,操作系统不会将磁盘中的文件加载到内存中,而是在内存中创建一个描述文件的结构(如下图struct file),该结构会管理一个缓冲区,内存和磁盘文件的数据交换都是通过这个缓冲区。示意图如下:
其次,由于文件操作是由进程调用了系统接口完成的,因此进程控制块(如下图struct task_struct)需要记录这些描述文件的结构,因此进程控制块会申请一块创建一个结构(如下图struct files_struct)描述进程操作的文件,然后在进程控制块中使用一个变量(如下图struct files_struct*)记录这个进程操作的文件的地址。示意图如下:
最后,由于一个进程可以操作的文件数量众多,因此描述进程操作的文件的结构(如下图struct files_struct)中,会用一个数组(如下图struct file* fd_array[])记录所有该进程操作的文件的描述结构(如下图struct file)的地址,而这个数组的下标就是文件描述符。示意图如下:
说明: 文件描述符的存在使得进程管理和文件管理处于轻耦合的状态,二者之间只是使用了文件描述结构的指针联系在了一起。
文件数据交换的原理
-
进程调用系统接口
write
之后,操作系统会将要传入到磁盘文件的数据拷贝至该文件描述结构中管理的缓冲区,然后操作系统会根据自身的刷新策略,在合适的时候将数据刷新到磁盘文件中。 -
进程调用系统接口
read
之后,操作系统会将磁盘文件中的数据拷贝至该文件描述结构中管理的缓冲区,然后将该缓冲区中的内容拷贝至进程指定的位置中。
理解“一切皆文件”
在Linux操作系统中,一切的外设都被看作是文件,因此说“Linux下一切皆文件”。关于“一切皆文件”的理解如下:
首先,操作系统在管理硬件时,并不是直接管理硬件设备的,二者之间要通过驱动程序这一中间软件来完成交互,外设与计算机的交互方式就是数据写入和读取,因此在各个硬件对应的驱动程序中会存在该硬件的读写方法。示意图如下:
虽然驱动程序都设计了对应硬件的读写方法声明,但并不是都有具体实现的,比如键盘只有读取方法,无法向键盘写入。
其次,Linux操作系统会使用描述文件的结构(如下图struct file)来描述每一个外设,并且该结构中会使用函数指针的形式来记录驱动程序所提供的读写方法,然后操作系统要进行外设数据的写入时,只需要将数据写入至文件对应的缓冲区,然后使用函数指针调用对应的函数方法将数据写入写入外设,操作系统读取外设数据时,只需要调用函数指针调用对应的方法将数据写入文件对应的缓冲,然后从缓冲区中读取数据。示意图如下:
由于所有的外设都被统一的使用了描述文件的结构描述,并且进程都是利用缓冲区交换数据,调用对应的读写方法进行读写,其操作方式和文件的操作方式相同,因此从进程的角度看外设和磁盘文件是一样的,因此才说“Linux下一切皆文件”。
进程默认文件描述符
进程在运行时,会默认打开三个文件,分别是标准输入、标准输出、标准错误。为了验证这编写如下代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = open(LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);printf("fd:%d\n", fd);close(fd);return 0;
}
编译代码运行并查看结果:
文件描述符代表的是记录进程操作文件的结构的数组的下标,文件描述符的使用规则是从数组起始位置开始,找到第一个没被使用的位置,进程运行时默认打开了标准输入(对应文件描述符为0)、标准输出(对应文件描述符为1)、标准错误(对应文件描述符为2),因此再打开的文件的文件描述符是从3开始。所以能够看到上面的代码打开文件获取的文件描述符为3。
文件描述符和编程语言的关系
在C语言标准库中使用了struct FILE
描述文件信息,将标准输入命名为stdin
,标准输出命名为stdout
,标准错误命名为stderr
,由于Linux操作系统的提供的文件操作接口都需要使用文件描述符,因此struct FILE
需要包含文件描述符字段。C语言进行进程文件操作和struct FILE
强相关,C语言库函数中提供的文件操作函数都会利用struct FILE
中记录的文件描述符来调用Linux系统接口来完成。在Linux系统下C语言的struct FILE
会有一个变量 _fileno
记录文件描述符。为了验证这编写如下代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{printf("stdin:%d\n", stdin->_fileno);printf("stdout:%d\n", stdout->_fileno);printf("stderr:%d\n", stderr->_fileno);FILE* fp = fopen("LOG", "w");printf("fp:%d\n", fp->_fileno);fclose(fp);return 0;
}
编译代码运行并查看结果:
在Linux操作系统中,无论何种编程语言,只要使用文件操作必然需要对文件描述符进行一定的封装来使用,才能完成Linux操作系统下的文件操作。
重定向
输出重定向
输出重定向是将进程原本应该打印到显示器上的数据,输出到文件中。
实现输出重定向的原理: 输出函数是将文件描述符1作为参数调用系统接口函数实现的,修改文件描述符表中1号位置指向的文件,即可完成输出重定向。输出函数的封装中只是使用文件描述符1,无法知晓输出位置的改变。落实到C语言中就是printf
是向stdout
输出数据,但是stdout
也只是封装了文件描述符1,修改文件描述符表中的指向的文件,printf
也无法知晓。
为了模式实现输出重定向编写如下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = close(1);open(LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);printf("hello world\n");printf("hello world\n");printf("hello world\n");close(fd);return 0;
}
编译代码运行查看结果:
输入重定向
输入重定向是将进程原本应该从键盘中获取数据,变为从文件中获取数据。
实现输入重定向的原理: 输入函数是将文件描述符0作为参数调用系统接口函数实现的,修改文件描述符表中0号位置指向的文件,即可完成输入重定向。输入函数的封装中只是使用文件描述符0,无法知晓输入位置的改变。落实到C语言中就是scanf
是从stdin
获取数据,但是stdin
也只是封装了文件描述符0,修改文件描述符表中的指向的文件,scanf
也无法知晓。
为了模式实现输入重定向编写如下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{close(0);int fd = open(LOG, O_RDONLY);int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("%d %d\n", a, b);close(fd);return 0;
}
编译代码运行查看结果:
追加重定向
追加重定向是将进程原本应该追加打印到显示器上的数据,变为追加打印到文件中。
实现追加重定向的原理: 将输出函数使用的文件描述符1指向改为指定文件,并且在打开文件时使用追加的方式。
为了模式实现追加重定向编写如下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{close(1);int fd = open(LOG, O_WRONLY | O_CREAT | O_APPEND, 0666);printf("hello world\n");printf("hello world\n");printf("hello world\n");close(fd);return 0;
}
编译代码运行查看结果:
说明: 在实现重定向时也可以选择如下的输入或输出方式:
fscanf(stdin, ...); //等效于scanf
fprintf(stdout, ...); //等效于printf
使用指令完成重定向
Linux操作系统中可以使用指令完成重定向,为了验证编写如下代码:
#include <stdio.h>int main()
{printf("hello->printf\n");fprintf(stdout, "hello->fprintf stdout\n");fprintf(stderr, "hello->fprintf stderr\n");return 0;
}
编译代码运行查看结果:
./myfile > log.txt
将./myfile的输出重定向到 log.txt文件中,也就是将 log.txt的文件信息写入到该进程的文件描述符1中,2>&1
是将该进程的文件描述符1的文件信息写入到文件描述符2中。
重定向系统调用
Linux操作系统中提供了能够重定向的系统调用dup2
:
//dup2函数所在的头文件和声明
#include <unistd.h>int dup2(int oldfd, int newfd);
- dup2函数会将输出到文件描述符newfd的数据改为输出到文件描述符oldfd对应的文件中。
- dup2函数会将文件描述符oldfd的文件信息写入到文件描述符newfd的文件信息中。
为了验证dup2
编写如下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define LOG "log.txt"int main()
{int fd = open(LOG, O_WRONLY | O_CREAT | O_TRUNC);dup2(fd, 1);printf("this is printf\n");fprintf(stdout, "this is fprintf->stdout\n");close(fd);return 0;
}
编译代码运行查看结果:
C语言文件缓冲区
在C语言标准库中提供的struct FILE
中包含了缓冲区字段,使用C语言库函数中的文件操作向文件写入数据,C语言标准库只会将数据写入到对应文件的struct FILE
中的缓冲区,然后结合一定的刷新策略将缓冲区中的内容刷新到Linux操作系统中的文件缓冲区中。示意图如下:
缓冲区刷新策略:
-
无缓冲 – 数据不经过缓冲区直接写入操作系统
-
行缓冲 – 数据写入缓冲区后遇到
'\n'
,将'\n'
及以前的数据写入操作系统 -
全缓冲 – 缓冲区写满后将数据写入操作系统
-
显示器采用的刷新策略:行缓冲
-
普通文件采用的刷新策略:全缓冲
将缓冲区中的数据刷新到操作系统需要使用系统调用,而系统调用的使用要花费大量时间,因此采用缓冲区刷新策略,可以提高效率。
为了验证C语言struct FILE
中的缓冲区编写如下代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>#define LOG "log.txt"int main()
{fprintf(stdout, "hello fprint->stdout\n");const char* msg = "hello write\n";write(1, msg, strlen(msg));fork();return 0;
}
编译代码运行查看结果:
由于不进行重定向时,打印数据的位置是显示器,采用的是行缓冲的策略,因此数据会在创建子进程前被刷新到操作系统,进行重定向后打印数据的位置是普通文件,采用的是全缓冲的策略,但数据不够写满缓冲区,因此数据会在进程解说,也就是创建子进程之后刷新,而无论父子进程哪一个先刷新都会发生写时拷贝,导致最终数据被刷新到操作系统两次。调用系统调用wrire
是直接写入操作系统因此不受影响。
相关文章:

[Linux]文件描述符(万字详解)
[Linux]文件描述符 文章目录 [Linux]文件描述符文件系统接口open函数close函数write函数read函数系统接口与编程语言库函数的关系 文件描述符文件描述符的概念文件数据交换的原理理解“一切皆文件”进程默认文件描述符文件描述符和编程语言的关系 重定向输出重定向输入重定向追…...

RenderTarget导出成图片,CineCamera相机
一、获取Cinecamera相机图像 1.1、启用UE自带插件 1.2、在UE编辑器窗口栏找到Composure合成,打开窗口 1. 3、右键空白处,新建合成,默认名称为 0010_comp;再右键新建的 0010_comp,新建图层元素 CGLayer层,默…...

深入探讨Java虚拟机(JVM):执行流程、内存管理和垃圾回收机制
目录 什么是JVM? JVM 执行流程 JVM 运行时数据区 堆(线程共享) Java虚拟机栈(线程私有) 什么是线程私有? 程序计数器(线程私有) 方法区(线程共享) JDK 1.8 元空…...

3D 碰撞检测
推荐:使用 NSDT场景编辑器快速搭建3D应用场景 轴对齐边界框 与 2D 碰撞检测一样,轴对齐边界框 (AABB) 是确定两个游戏实体是否重叠的最快算法。这包括将游戏实体包装在一个非旋转(因此轴对齐)的框中&#…...

Unity Canvas动画不显示的问题
问题描述: 我通过角色创建了一个walk的动画,当我把这个动画给到Canvas里面的一个image上,这个动画就不能正常播放了,经过一系列的查看我才发现,canvas里面动画播放和非canvas得动画播放,他们的动画参数是不一样的。一个…...

NSSCTF2nd与羊城杯部分记录
文章目录 前言[NSSCTF 2nd]php签到[NSSCTF 2nd]MyBox[NSSCTF 2nd]MyHurricane[NSSCTF 2nd]MyJs[NSSCTF 2nd]MyAPK羊城杯[2023] D0nt pl4y g4m3!!!羊城杯[2023]ezyaml羊城杯[2023]Serpent羊城杯[2023]EZ_web羊城杯[2023]Ez_misc总结 前言 今天周日,有点无聊没事干&a…...

数据库(一) 基础知识
概述 数据库是按照数据结构来组织,存储和管理数据的仓库 数据模型 数据库系统的核心和基础是数据模型,数据模型是严格定义的一组概念的集合。因此数据模型一般由数据结构、数据操作和完整性约束三部分组成。数据模型主要分为三种:层次模型,网状模型和关…...

vue从零开始学习
npm install慢解决方法:删掉nodel_modules。 5.0.3:表示安装指定的5.0.3版本 ~5.0.3:表示安装5.0X中最新的版本 ^5.0.3: 表示安装5.x.x中最新的版本。 yarn的优点: 1.速度快,可以并行安装 2.安装版本统一 项目搭建: 安装nodejs查看node版本:node -v安装vue clie : np…...

dji uav建图导航系列(三)模拟建图、导航
前面博文【dji uav建图导航系列()建图】、【dji uav建图导航系列()导航】 使用真实无人机和挂载的激光雷达完成建图、导航的任务。 当需要验证某一个slam算法时,我们通常使用模拟环境进行测试,这里使用stageros进行模拟测试,实际就是通过模拟器,虚拟一个带有传感器(如…...

PixelSNAIL论文代码学习(1)——总体框架和平移实现因果卷积
文章目录 引言正文目录解析README.md阅读Setup配置Training the model训练模型Pretrained Model Check Point预训练的模型训练方法 train.py文件的阅读model.py文件阅读h12_noup_smallkey_spec模型定义_base_noup_smallkey_spec模型实现一、定义因果卷积过程通过平移实现因果卷…...

Python大数据处理利器之Pyspark详解
摘要: 在现代信息时代,数据是最宝贵的财富之一,如何处理和分析这些数据成为了关键。Python在数据处理方面表现得尤为突出。而pyspark作为一个强大的分布式计算框架,为大数据处理提供了一种高效的解决方案。本文将详细介绍pyspark…...

S905L3A(M401A)拆解, 运行EmuELEC和Armbian
关于S905L3A / S905L3AB S905Lx系列没有公开资料, 猜测是Amlogic用于2B的芯片型号, 最早的 S905LB 是 S905X 的马甲, 而这个 S905L3A/S905L3AB 则是 S905X2 的马甲, 因为在性能评测里这两个U的得分几乎一样. S905L3A/S905L3AB 和 S905X2, S905X3 一样 GPU 是 G31, 相比前一代的…...

stack和queue容器
1 stack 基本概念 概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口 栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为 栈中进入数据称为 — 入栈 push 栈中弹出数据称为 — 出栈 pop 2 stack 常用…...

面向对象基础
文章目录 面向对象基础一.面向对象介绍二.设计对象并使用三.封装四.This关键字五.构造方法六.标准的Javabean类七.对象内存图八.基本数据类型和引用数据类型九.成员和局部 面向对象基础 一.面向对象介绍 面向:拿,找 对象:能干活的东西 面向对象编程:找东西来做对应的事情 …...

spring集成mybatis
1、新建一个javaEE web项目 2、加入相关依赖的坐标 <dependencies><!--数据系列:mybatis,mysgl,druid数据源,junit--><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</grou…...

抽象轻松c语言
目 c语言 c程序 c语言的核心在于语言,语言的作用是进行沟通,人与人之间的信息交换 人与人之间的信息交换是会有信息空白(A表达信息,B接受信息,B对信息的处理会与A所以表达的信息具有差距,这段差距称为信…...

Redis布隆过滤器原理
其实布隆过滤器本质上要解决的问题,就是防止很多没有意义的、恶意的请求穿透Redis(因为Redis中没有数据)直接打入到DB。它是Redis中的一个modules,其实可以理解为一个插件,用来拓展实现额外的功能。 可以简单理解布隆…...

写代码时候的命名规则、命名规范、命名常用词汇
版权声明 这个大部分笔记是观看up主红桃A士的视频记录下来的,因为本人在学习的过程中也经常出现类似的问题,并且觉得Up主的视频讲解很好,做此笔记反复学习,若有侵权请联系删除,此推荐视频地址:【改善丑陋的…...

Linux之iptables防火墙
一.网络安全技术 ①入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报警和事后监督为主,提供有针对性的指导措施和安全决策依据,类 似于…...

启动服务报错:Command line is too long Shorten command line for xxx or also for Spri
ommand line is too long. Shorten command line for ProjectApprovalApplication or also for Spring Boot default configuration. 启动springboot 项目的时候报错 解决方案: 点击提示中的:default:然后在弹出窗口中选择:JAR xx…...

docker安装elasticsearch、kibana
安装过程中,遇到最大的问题就是在安装kibana的时候发现 一直连接不上 elasticsearch。最后解决的问题就是 我通过 ifconfig en0 | grep inet| awk {print $2} 在mac中找到本机的ip,然后去到kibana容器中 修改 vi config/kibana.yml中的elasticsearch.hos…...

前端 CSS - 如何隐藏右侧的滚动条 -关于出现过多的滚动条导致界面不美观
1、配置 HTML 标签,隐藏右侧的滚动条 CSS 配置:下面两个一起写进进去,适配 IE、火狐、谷歌浏览器 html {/*隐藏滚动条,当IE下溢出,仍然可以滚动*/-ms-overflow-style:none;/*火狐下隐藏滚动条*/overflow:-moz-scroll…...

2.神经网络的实现
创建神经网络类 import numpy # scipy.special包含S函数expit(x) import scipy.special # 打包模块 import pickle# 激活函数 def activation_func(x):return scipy.special.expit(x)# 用于创建、 训练和查询3层神经网络 class neuralNetwork:# 初始化神经网络def __init__(se…...

合宙Air724UG LuatOS-Air LVGL API控件-键盘 (Keyboard)
键盘 (Keyboard) LVGL 可以添加触摸键盘,但是很明显,使用触摸键盘的话必须要使用触摸的输入方式,否则无法驱动键盘。 示例代码 function keyCb(obj, e)-- 默认处理事件lvgl.keyboard_def_event_cb(keyBoard, e)if(e lvgl.EVENT_CANCEL)the…...

pytorch深度学习实践
B站-刘二大人 参考-PyTorch 深度学习实践_错错莫的博客-CSDN博客 线性模型 import numpy as np import matplotlib.pyplot as pltx_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0]def forward(x):return x * wdef loss(x, y):y_pred forward(x)return (y_pred - y) ** 2# …...

直方图反向投影(Histogram Backprojection)
直方图反向投影(Histogram Backprojection)是一种在计算机视觉中用于对象检测和图像分割的技术。它的原理基于图像的颜色分布,允许我们在一幅图像中找到与给定对象颜色分布相匹配的区域。这个技术常常用于图像中的目标跟踪、物体识别和图像分…...

day32 泛型 数据结构 List
一、泛型 概述 JDK1.5同时推出了两个和集合相关的特性:增强for循环,泛型 泛型可以修饰泛型类中的属性,方法返回值,方法参数, 构造函数的参数 Java提供的泛型类/接口 Collection, List, Set,Iterator 等 …...

DW-AHB Central DMAC
文章目录 AHB Central DMAC —— Design Ware AHB Central DMAC —— Design Ware AHB(Adavenced High-performace BUS) Central DMAC(Direct Memory Access Controller) : 一个高性能总线系统。 作用:在嵌入式系统种连接高速设备,如处理器内存&#x…...

JavaScript设计模式(四)——策略模式、代理模式、观察者模式
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...

JS画布的基本使用
直线 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> <style> #myname{ border: 1px solid red; /* background: linear-gradient(to righ…...