【Linux】基础IO--文件基础知识/文件操作/文件描述符

news2024/11/16 3:43:49

文章目录

  • 一、文件相关基础知识
  • 二、文件操作
    • 1.C语言文件操作
    • 2.操作系统文件操作
      • 2.1 比特位传递选项
      • 2.2 文件相关系统调用
      • 2.3 文件操作接口的使用
  • 三、文件描述符fd
    • 1.什么是文件描述符
    • 2.文件描述符的分配规则

一、文件相关基础知识

我们对文件有如下的认识:

1.文件 = 文件内容 + 文件属性,即文件包括文件的内容和属性两个部分

2.空文件只是文件的内容为空,但是文件的属性不为空,所以空文件也需要占据磁盘的空间

3.由于文件包括内容和属性,那么我们对文件的操作可以分为对文件内容非操作,对文件的属性进行操作以及对文件的内容和属性进行操作

3.Linux/windows中目录都采用多叉树的形式进行表示,即树的中间节点表示目录,树的叶子节点表示文件,所以我们可以使用文件路径+文件名来唯一的标识一个文件

4.在对文件进行访问的时候,如果没有指定文件的路径,那么默认在当前路径下对文件进行访问,当前路径指的是当前进程所在的工作路径

5.在C语言中,当我们把fopen,fclose,fwrite,fread等函数接口的程序编译链接形成可执行程序,如果我们运行该可执行程序,那么对应的函数就不会被调用,则对应的文件操作也就不会被执行,因为函数在运行时才会建立栈帧,所以对文件的操作本质上是进程对文件的操作

6.我们知道,我们要访问一个文件,那么就必须先打开这个文件,而文件存储在磁盘上,由于计算机结构的原因,磁盘上的文件必须通过OS才能和进程进行交互,所以文件打开是由用户进程和OS配合来完成的—用户进程调用文件的接口,OS系统实现这些系统调用接口

7.磁盘上存在许许多多的文件,并不是所有的这些文件都被打开了,所以文件分为被打开的文件和没有被打开的文件,那些没有被打开的文件被成为文件系统

所以,文件操作的本质是进程与被打开文件的关系

二、文件操作

在谈论文件操作之前,我们需要了解 语言层面上的文件操作与操作系统层面上的文件操作的关系

我们知道,每一种语言都有其对应的文件操作,包括面向过程语言C,面向对象语言C++/java,静态编译语言go,解释型语言python,甚至包括脚本语言shell等等,但是每一种语言对文件操作提供的接口都不相同,这样就会导致我们的学习成本变得很高。

站在语言的角度我们觉得是这样的,但是站在操作系统的角度就不是这样了 ,我们知道计算机的软硬件体系结构之后,就会知道操作系统为了同时满足 保护自身安全 与 为上层用户提供良好的(稳定的,安全的,高效的)服务,会给用户提供访问软硬件的系统调用接口,同时,为了降低用户使用成本,人们又在系统调用接口的基础上开发了用户操作接口,其中包括shell外壳与各种语言的函数库,而用户就是通过调用用户操作接口类完成指令,开发与管理等操作

在这里插入图片描述

也就是说,站在操作系统的角度,虽然每一种语言的文件操作接口都不一样,但是这些接口底层调用的一定是同一种系统调用接口,因为操作系统是计算机管理软硬件资源的软件,进程想要访问文件只能通过调用操作系统提供的系统调用接口,我们使用的fopen,fwrite,fclose等等接口底层也是调用系统调用接口

而系统调用接口只有一套,语言有无数种,每一种又不一样,那么我们学习文件操作只需要学习操作系统提供的系统调用中有关文件操作的接口即可,学习了系统调用就相当于学习了底层,以后我们再学习语言的文件操作时只需要学习一些新的方式即可,但是底层是不变的,这样就会大大降低学习的成本

1.C语言文件操作

在学习C语言的文件操作之前,我们先回顾一下C语言的操作函数

C语言文件操作接口

函数名函数功能
fopen打开指定文件
fclose关闭指定文件
fwrite以二进制的形式向文件中写入数据
fread以二进制的形式从文件中读取数据
fscanf把文件中的数据格式化的读取到内存中
fprintf把内存中的数据格式化的写入到文件中

总结:

  1. fopen:用于打开文件,并返回一个文件指针,可以指定不同的打开模式(如只读、只写、追加等)和文件类型(文本或二进制)。配合其他文件操作函数使用,如fprintffscanf等。

  2. fclose:用于关闭文件,关闭后文件指针指向的文件将不可访问。

  3. fread:从文件中读取数据到指定的内存缓冲区中,可以指定要读取的数据块的大小和数量。

  4. fwrite:将指定大小的数据块从内存缓冲区写入文件中,可以指定要写入的数据块的大小和数量。

  5. fseek:设置文件指针的位置,用于定位读写位置。可以通过设置相对于文件开头、文件末尾或当前位置的偏移量来移动文件指针。

  6. ftell:获取文件指针的当前位置,返回当前位置的偏移量。

  7. rewind:将文件指针重置到文件的起始位置,相当于调用fseek(file, 0, SEEK_SET)

  8. feof:检查文件指针是否已到达文件末尾,返回非零值表示到达文件末尾。

  9. fgets:从文件中读取一行数据到指定的字符数组中。

  10. fprintf:将格式化的数据写入文件中。

需要注意的是,在使用文件操作接口时,应当检查返回值以确保操作是否成功,并且在不需要使用文件时要及时关闭文件以释放资源。

C语言文件打开的几种方式

文件打开方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件建立一个新的文件
“a”(追加)向文本文件尾部添加数据建立一个新的文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加)向一个二进制文件尾部添加数据出错
“r+”(读写)为了读和写,打开一个文件文件出错
“w+”(读写)为了读和写,建立一个新的文件建立一个新的文件
“a+”(读写)打开一个文件,在文件的尾部进行读写建立一个新的文件

总结:

  1. r(只读):以只读方式打开文件。文件必须存在,否则打开失败。
  2. w(只写):以只写方式打开文件。如果文件存在,则文件内容会被截断为空;如果文件不存在,则会创建新文件。
  3. a(追加写):以追加写入方式打开文件。如果文件存在,则新的数据会追加到文件末尾;如果文件不存在,则会创建新文件。
  4. r+(读写):以读写方式打开文件。文件必须存在,允许读取和写入文件内容。
  5. w+(读写,创建新文件):以读写方式打开文件。如果文件存在,则文件内容会被截断为空;如果文件不存在,则会创建新文件。
  6. a+(追加读写):以追加读写方式打开文件。如果文件存在,则新的数据会追加到文件末尾;如果文件不存在,则会创建新文件。允许读取和写入文件内容。

需要注意的是,以上文件打开模式只适用于文本文件。对于二进制文件,可以在以上模式后添加b来表示二进制模式(例如rbwb等)。

此外,还有一些其他的文件打开模式,如rb+wb+等。这些模式在于读取和写入的组合方式,具体的操作方式和特性与上述模式类似,但会有一些细微的区别。

在选择文件打开模式时,需要根据具体的需求和操作来确定使用哪种模式。例如,如果需要只读取文件内容,则使用r模式;如果需要追加写入内容,则使用aa+模式;如果需要同时读取和写入文件内容,则使用r+w+a+模式,具体选择根据是否需要创建新文件或截断文件内容来决定。

C语言文件操作的例子

1.向文件中写入数据

#include <stdio.h>

#define FILE_NAME "log.txt"

int main()
{
    FILE *fp = fopen(FILE_NAME, "w");
    if (NULL == fp)
    {
        perror("fopen failed");
        return 1;
    }

    int cnt = 5;
    while (cnt)
    {
        fprintf(fp,"%s:%d\n","hello world",cnt--);
    }
    fclose(fp);
    
    return 0;
}

在这里插入图片描述

2.从文件中读取数据

#include <stdio.h>
#include <string.h>
#define FILE_NAME "log.txt"

int main()
{
    FILE *fp = fopen(FILE_NAME, "r");
    if (NULL == fp)
    {
        perror("fopen failed");
        return 1;
    }

    char buffer[64];
    while(fgets(buffer,sizeof (buffer)-1,fp)!=NULL)
    {
        buffer[strlen(buffer) - 1] = 0;
        puts(buffer);
    }
    
    fclose(fp);
    
    return 0;
}

在这里插入图片描述

注意:

1.r(只读),w(只写), r+(读写,不存在出错),w+(读写, 不存在创建), a(append, 追加), a+()

2.以w方式单纯的打开文件,无论是否写入数据,c语言会自动清空内部的数据

3.通过fwrite创建出来的文件log.txt,其权限是664,这是由于普通文件的默认权限为0666,linux默认的umask为0002,而文件的最终权限等于默认权限 & ~umask,所以log.txt的权限为0664

在这里插入图片描述

2.操作系统文件操作

2.1 比特位传递选项

C语言常通过一个整形来传递选项,但是当选项较多时,每一个选项都用一个整形来进行传递,那么函数的参数就会很多,这时就提出了使用一个比特位来传递一个选项,这样一个整形有32个比特位,就可以传递32种选项,多个传递时使用 | 运算即可,具体案例如下:

#include <stdio.h>

// 每一个宏只占用一个比特位,该比特位为1说明该选项成立,且各个宏的位置不重叠
#define OPTION_ONE (1 << 0)
#define OPTION_TWO (1 << 1)
#define OPTION_TREE (1 << 2)
#define OPTION_FOUR (1 << 3)

void show(int flags)
{
    // flags与上面哪个选项匹配,就执行对应的操作
    // 按位与的结果为1,说明flags对应的比特位为1
    if (flags & OPTION_ONE)
        printf("OPTION_ONE\n");
    if (flags & OPTION_TWO)
        printf("OPTION_TWO\n");
    if (flags & OPTION_TREE)
        printf("OPTION_TREE\n");
    if (flags & OPTION_FOUR)
        printf("OPTION_FOUR\n");
}

int main()
{
    // 主函数中通过传递不同的选项来达到不同的效果
    show(OPTION_ONE);
    printf("-----------------------\n");
    show(OPTION_TWO);
    printf("-----------------------\n");
    show(OPTION_ONE | OPTION_TWO);
    printf("-----------------------\n");
    show(OPTION_ONE | OPTION_TWO | OPTION_TREE);
    printf("-----------------------\n");
    show(OPTION_ONE | OPTION_TWO | OPTION_TREE | OPTION_FOUR);
    printf("-----------------------\n");

    return 0;
}

在这里插入图片描述

如上,我们将宏与比特位对应,然后在show函数中编写每一个宏对应的功能,之后我们就可以在其他函数中通过调用show函数并传递对应的选项来达到我们想要的结果,并且我们可以通过按位或来实现同时传递几个选项

2.2 文件相关系统调用

open & close

函数功能

open:打开或创建一个文件,

close:关闭一个文件

在这里插入图片描述

在这里插入图片描述

函数参数

int open(const char* pathname, int flags);
int open(const cahr *pathname, int flags, mode_t mode);
# 头文件:<sys/types.h>	 <sys/stat.h>  <fcntl.h> 
# pathname: 文件路径/文件名
# flags: 打开文件时,可以传入多个参数选项,用一个或者多个宏常量进行“或”运算,构成flags(比特位传递选项)
参数:
 O_RDONLY: 只读打开
 O_WRONLY: 只写打开
 O_RDWR : 读,写打开
 这三个常量,必须指定一个且只能指定一个
 O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
 O_APPEND: 追加写
# mode: 指定创建新文件时文件的默认权限(文件最终权限还要受umask的影响)
# 函数返回值:int:文件打开或创建成功返回文件对应的文件描述符(整形),失败返回-1int close(int fd);
# 头文件:<unistd.h>
# fd:目标文件对应的文件描述符
# int:函数返回值,关闭成功返回0,关闭失败返回-1
文件打开方式-含义如果指定文件不存在
O_RDONLY以只读形式打开出错
O_WRONLY以只写形式打开出错
O_RDWR以读写形式打开出错
O_APPEND向文本文件尾添加数据出错
O_CREAT如果文件不存在,创建新文件建立一个新的文件
O_TRUNC打开文件时清空文件中之前的数据出错

上述这些宏表示不同的文件打开方式,其底层原理和我们上面讲的 通过比特位传递选项 是一样的,我们可以在调用 open 函数时传递一个或多个宏,来实现不同的文件打开方式。

同时,我们可以通过文件操作的系统调用接口和封装后的C语言文件操作接口还是存在很多细节上的不同的,如下:

C语言以 “w” 的方式打开文件,若文件不存在会自动创建一个新文件,而系统调用目标文件不存在直接报错,除非指定了 O_CREAT 选项;
C语言以 “w” 方式打开文件时会自动清空之前文件中的数据,而系统调用则是逐个字符进行覆盖,并不会提前清空文件中的数据,如果要清空必须指定 O_TRUNC 选项;
需要注意的是,O_CREAT 是一个建议性选项,即当文件存在时我们传递此选项也不会报错;同时,文件不存在创建文件时需要传递 mode 选项来指定新文件的访问权限;

上面这些细节的不同也从侧面印证了C语言文件操作接口是对系统调用接口的封装 – “w” 选项会自动清空旧数据、创建新文件,又比如创建新文件时C语言不用手动传递 mode 选项指定权限等等,这些细节都隐藏在了函数的具体实现中。

write 与 read

函数功能

write:向文件中写数据; read:从文件中读数据;

在这里插入图片描述

在这里插入图片描述

函数参数

ssize_t write(int fd, const void* buf, size_t count);
# 头文件:<unistd.h>
# fd:目标文件的文件描述符
# buf:要写入数据的来源
# count:要写入数据的字节数
# ssize_t:函数返回值,写入成功返回成功写入的字节数,写入失败返回-1

ssize_t read(int fd, void* buf, size_t count);
# 头文件:<unistd.h>
# fd:目标文件的文件描述符
# buf:读取数据存放的位置
# count:要读取数据的字节数
# ssize_t:函数返回值,读取成功返回读取写入的字节数,读到文件末尾返回0,读取失败返回-1

2.3 文件操作接口的使用

操作系统系统调用文件相关接口的使用和C语言文件操作接口的使用总体上是差不多的,只是一些细节上有所不同。

1.向文件中写数据

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define FILE_NAME "log.txt"

int main()
{
    // 创建文件并以只写形式打开,并指定文件的默认权限为0666(还受umask的影响)
    // 同时,我们可以通过umask接口手动设置当前进程的文件掩码,而不使用从父进程继承过来的umask
    umask(0000);
    int fd = open(FILE_NAME, O_WRONLY | O_CREAT, 0666);
    if (fd < 0)
    {
        perror("open failed");
        return 1;
    }

    int cnt = 5;
    char buffer[64];

    while (cnt)
    {
        sprintf(buffer, "%s:%d\n", "hello world", cnt--);
        // 注意:这里strlen求得的长度不用加1,因为字符串以'\0'结尾只是C语言的特性,而文件中并不这样规定
        write(fd, buffer, strlen(buffer));
    }

    close(fd);
    return 0;
}

注意:

1.建 文件时我们通过 umask 系统调用将 umask 设置为了 0000(第一个0代表八进制),然后将 mode 设置为 0666,所以 文件的最终权限为 默认权限 & ~umask – 0666 & ~0000 = 0666;

在这里插入图片描述

在这里插入图片描述

2.向文件中写入数据时如果不指定 O_TRUNC 选项,新数据就会逐字节覆盖原数据,所以有时候就会出现下面只覆盖了一部分原数据的情况:

在这里插入图片描述

3.C语言中字符串以 ‘\0’ 结尾,但是文件中字符串并不以 ‘\0’ 结尾,所以我们向文件中写入字符串时,count 设置为 strlen(str) 就行,不用把最后面的 ‘\0’ 字符加上,如果加上了就会出现部分乱码:

在这里插入图片描述

2.从文件中读数据

#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define FILE_NAME "log.txt"

int main()
{
    // 创建文件并以只写形式打开,并指定文件的默认权限为0666(还受umask的影响)
    // 同时,我们可以通过umask接口手动设置当前进程的文件掩码,而不使用从父进程继承过来的umask
    umask(0000);
    int fd = open(FILE_NAME, RD_ONLY, 0666);
    if (fd < 0)
    {
        perror("open failed");
        return 1;
    }

    char buffer[1024];
    ssize_t num = read(fd, buffer, sizeof(buffer) - 1);
    if (num > 0)
        buffer[num] = 0; // 0, '\0', NULL -> 0
    printf("%s", buffer);
    close(fd);
    return 0;
}

在这里插入图片描述

由于C语言字符串以 ‘\0’ 结尾,而文件中的字符串数据并不包含 ‘\0’,所以这里我们需要预留一个位置,便于在数据量大于等于1024字节这种极端情况下 buffer中仍有空间来放置 ‘\0’。

三、文件描述符fd

1.什么是文件描述符

我们知道,文件操作本质上是进程与被打开文件之间的关系,同时,一个进程可以打开多个文件,且操作系统同时运行着许多个进程;那么操作系统中就一定存在着大量被打开的文件,那这些被打开的文件要不要被操作系统管理起来呢?答案是肯定的。

如何管理呢? 答案是先描述,再组织,即将文件的所有属性都总结到一个结构体中,并为每一个文件都创建一个结构体对象,再用一种数据结构将这些结构体对象组织起来,这样对众多被打开文件的管理就变成了对某一种数据结构的增删查改;Linux 中用于管理文件的内核数据结构叫做 struct file {} 结构体,其中包含了文件的大部分属性。

进程如何知道哪些被打开文件属于它呢?如图:

在这里插入图片描述

进程的 task_struct 里面有一个 struct files_struct *files 指针变量,它指向一个属于该进程的数据结构对象 struct files_struct,该对象里面包含了一个指针数组 struct file* fd_array[],即进程的文件描述符表,数组里面的每个元素都是指针,指向一个 struct file 对象,而这个数组的下标就是我们用户得到的文件描述符 fd。

也就是说,进程可以通过进程控制块中的 files 变量找到 files_struct 结构体,再通过 files_struct 中的文件描述符表具体下标中保存的地址找到具体文件的内核数据结构 file,从而实现数据的读取与写入。

总结:现在知道,文件描述符就是从0开始的小整数,当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件,于是就有了 file 结构体,表示一个已经打开的文件对象。而进程执行 open 系统调用,所以必须让进程和文件关联起来,于是每个进程都有一个 *files 指针,指向一张表 files_struct,该表最重要的部分就是包含一个指针数组,数组中每个元素都是一个指向打开文件的指针。所以,本质上,文件描述符就是该数组的下标,因此,只要拿着文件描述符,就可以找到对应的文件。
所以,文件描述符是从0开始的小整数,其本质是文件描述符表中的数组下标。

2.文件描述符的分配规则

我们知道了文件描述符是什么,那么文件描述符是如何进行分配的呢?

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define FILE_NAME(number) "log.txt"#number


int main()
{
    int fd1 = open(FILE_NAME(1),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd2 = open(FILE_NAME(2),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd3 = open(FILE_NAME(3),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd4 = open(FILE_NAME(4),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd5 = open(FILE_NAME(5),O_WRONLY | O_CREAT | O_TRUNC,0666);

    printf("fd1 : %d\n",fd1);
    printf("fd2 : %d\n",fd2);
    printf("fd3 : %d\n",fd3);
    printf("fd4 : %d\n",fd4);
    printf("fd5 : %d\n",fd5);

    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd5);

    return 0;
}

在这里插入图片描述

注:C语言 # 在宏当中的作用 – 将参数插入到字符串中。

从运行结果可以看到,文件描述符是连续分配且依次增大的,这也很合理,因为文件描述符本质上是数组下标,而连续增长正好是数组下标的特性;但是这里有一个很奇怪的地方 – 文件描述符是从3开始的,那么0、1、2号下标呢?这是由三个默认打开的标准流引起的。

标准输入、标准输出与标准错误流

我们在运行一个程序的时候,操作系统会自动为我们打开三个流 – 标准输入流 stdin、标准输出流 stdout、标准错误流 stderr,它们分别对应键盘文件、显示器文件与显示器文件,其文件描述符分别是 0号、1号和2号,所以我们打开其他文件时 fd 默认是从3号开始分配的。即Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.0,1,2对应的物理设备一般是:键盘,显示器,显示器

#include <stdio.h>

int main() {
    printf("stdin->fd:%d\n", stdin->_fileno);
    printf("stdout->fd:%d\n", stdout->_fileno);
    printf("stderr->fd:%d\n", stderr->_fileno);
    return 0;
}

在这里插入图片描述

注:Linux 系统调用 open 接口的返回值是文件描述符 fd,而C语言 fopen 接口的返回值是 FILE*,其中 FILE 是一个结构体类型;我们知道,fopen 底层调用的是 open 接口,而 fopen 又不使用 fd 作为函数返回值,那么 FILE 结构体里面就一定会封装一个变量来表示 fd;gcc 中这个变量是 _fileno;
既然系统默认打开三个文件,那么我们可不可以将其关闭呢?当然可以:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define FILE_NAME(number) "log.txt"#number

int main()
{
    close(0);
    close(2);
    int fd1 = open(FILE_NAME(1),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd2 = open(FILE_NAME(2),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd3 = open(FILE_NAME(3),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd4 = open(FILE_NAME(4),O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd5 = open(FILE_NAME(5),O_WRONLY | O_CREAT | O_TRUNC,0666);

    printf("fd1 : %d\n",fd1);
    printf("fd2 : %d\n",fd2);
    printf("fd3 : %d\n",fd3);
    printf("fd4 : %d\n",fd4);
    printf("fd5 : %d\n",fd5);

    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd5);

    return 0;
}

在这里插入图片描述

可以看到,当0号和2号文件描述符被关闭以后,系统将其分配给了新打开的文件 log.txt1 和 log.txt2。

注:close 关闭文件并不是将 fd 指向的 file 对象释放掉,而仅仅是让当前进程文件描述符表中的对应下标不再指向该 file 对象,因为同一个文件可能会被多个进程访问,特别是父子进程。

(其底层可以采用 f_count **引用计数 **的方式来实现,即当有指向该文件的进程关闭时文件计数减1,有指向该文件的进程打开时文件计数加1,当 f_count 为 0 时操作系统才释放该文件的内核数据结构,即真正意义上的关闭文件)

所以,文件描述符的分配规则是:从小到大依次搜寻,寻找未被使用的最小 fd 作为新打开文件的 fd,即在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1272897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C 语言-数组

1. 数组 1.1 引入 需求&#xff1a;记录班级10个学员的成绩 需要定义10个变量存在的问题:变量名起名困难变量管理困难需求&#xff1a;记录班级1000个学员的成绩 1.2 概念 作用&#xff1a;容纳 数据类型相同 的多个数据的容器 。 特点&#xff1a; 长度不可变容纳 数据类型…

python实现two way ANOVA

文章目录 目的&#xff1a;用python实现two way ANOVA 双因素方差分析1. python代码实现1 加载python库2 加载数据3 统计样本重复次数&#xff0c;均值和方差&#xff0c;绘制箱线图4 查看people和group是否存在交互效应5 模型拟合与Two Way ANOVA&#xff1a;双因素方差分析6 …

ELFK集群部署(Filebeat+ELK) 本地收集nginx日志 远程收集多个日志

filebeat是一款轻量级的日志收集工具&#xff0c;可以在非JAVA环境下运行。 因此&#xff0c;filebeat常被用在非JAVAf的服务器上用于替代Logstash&#xff0c;收集日志信息。 实际上&#xff0c;Filebeat几乎可以起到与Logstash相同的作用&#xff0c; 可以将数据转发到Logst…

融资经理简历模板

这份简历内容&#xff0c;以综合柜员招聘需求为背景&#xff0c;我们制作了1份全面、专业且具有参考价值的简历案例&#xff0c;大家可以灵活借鉴。 融资经理简历在线编辑下载&#xff1a;百度幻主简历 求职意向 求职类型&#xff1a;全职 意向岗位&#xff1a;融资经理 …

Python Pyvis库:可视化复杂网络结构的利器

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Pyvis库&#xff1a;可视化复杂网络结构的利器&#xff0c;全文4000字&#xff0c;阅读大约12钟。 在数据科学和网络分析领域&#xff0c;理解和可视化复杂网络结构是…

JeecgBoot低代码开发—Vue3版前端入门教程

JeecgBoot低代码开发—Vue3版前端入门教程 后端接口配置VUE3 必备知识1.vue3新特性a. https://v3.cn.vuejs.org/b.setup的用法c.ref 和 reactive 的用法d.新版 v-model 的用法e.script setup的用法 2.TypeScript基础 后端接口配置 如何修改后台项目路径 http://127.168.3.52:8…

Ubuntu systemd-analyze命令(系统启动性能分析工具:分析系统启动时间,找出可能导致启动缓慢的原因)

文章目录 Ubuntu systemd-analyze命令剖析目录简介systemd与systemd-analyze工作原理 安装和使用命令参数详解用例与示例显示启动时间&#xff08;systemd-analyze time&#xff09;列出启动过程中各个服务的启动时间&#xff08;systemd-analyze blame&#xff09;显示系统启动…

R语言单因素方差分析+差异显著字母法标注+逐行详细解释

R语言单因素方差分析 代码如下 df <- read.csv("data.csv",header TRUE,row.names 1) library(reshape2) df <- melt(df,idc()) names(df) <- c(trt, val) df aov1 <- aov(val~trt,datadf) summary(aov1)library(agricolae) data <- LSD.test(aov…

windows远程桌面登录,提示:“出现身份验证错误,要求的函数不受支持”

问题&#xff1a; windows登录远程桌面&#xff0c;提示&#xff1a;“出现身份验证错误&#xff0c;要求的函数不受支持”&#xff0c;如下图&#xff1a; 问题原因&#xff1a; windows系统更新&#xff0c;微软系统补丁的更新将 CredSSP 身份验证协议的默认设置进行了调…

【腾讯云云上实验室-向量数据库】个人对腾讯云向量数据库的体验心得

目录 前言Tencent Cloud VectorDB概念使用初体验腾讯云向量数据库的优势应用场景有哪些&#xff1f;未来展望番外篇&#xff1a;腾讯云向量数据库的设计核心结语 前言 还是那句话&#xff0c;不用多说想必大家都能猜到&#xff0c;现在技术圈最火的是什么&#xff1f;非人工智…

ZZULIOJ 2466: 楼上瞎说,楼下才是,Java

2466: 楼上瞎说&#xff0c;楼下才是 题目描述 《九章算术》的内容十分丰富&#xff0c;全书采用问题集的形式&#xff0c;收有246个与生产、生活实践有联系的应用问题&#xff0c;其中每道题有问&#xff08;题目&#xff09;、答&#xff08;答案&#xff09;、术&#xff…

【Vulnhub 靶场】【DriftingBlues: 9 (final)】【简单】【20210509】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/driftingblues-9-final,695/ 靶场下载&#xff1a;https://download.vulnhub.com/driftingblues/driftingblues9.ova 靶场难度&#xff1a;简单 发布日期&#xff1a;2021年05月09日 文件大小&#xff1a;738 …

编程之外,生活的美好航程

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

涵盖多种功能,龙讯旷腾Module第二期:电子结构及声子计算

Module是什么 在PWmat的基础功能上&#xff0c;我们针对用户的使用需求开发了一些顶层模块&#xff08;Module&#xff09;。这些Module中的一部分是与已有的优秀工具的接口&#xff0c;一部分是以PWmat的计算结果为基础得到实际需要的物理量&#xff0c;一部分则是为特定的计…

Jmeter接口测试:jmeter_HTTP Cookie管理器看这一篇文章就够了

HTTP Cookie管理器 HTTP Cookie管理器可以像浏览器一样自动存储和发送cookie&#xff0c;以这种自 动收集的方式收集到的cookie不会在cookie manager中进行展示&#xff0c;但是运行后&#xff0c; 可以通过 查看结果树&#xff08;监听器&#xff09;可以查看到cookie信息 除…

WPF实战项目十九(客户端):修改RestSharp的引用

修改HttpRestClient&#xff0c;更新RestSharp到110.2.0&#xff0c;因为106版本和110版本的代码不一样&#xff0c;所以需要修改下代码 using Newtonsoft.Json; using RestSharp; using System; using System.Threading.Tasks; using WPFProjectShared;namespace WPFProject.S…

中国毫米波雷达产业分析4——毫米波雷达企业介绍

一、矽典微 &#xff08;一&#xff09;公司简介 矽典微致力于实现射频技术的智能化&#xff0c;专注于研发高性能无线技术相关芯片&#xff0c;产品广泛适用于毫米波传感器、下一代移动通信、卫星通信等无线领域。 整合自身在芯片、系统、软件、算法等领域的专业能力&#xf…

【驱动】SPI驱动分析(四)-关键API解析

关键API 设备树 设备树解析 我们以Firefly 的SPI demo 分析下dts中对spi的描述&#xff1a; /* Firefly SPI demo */ &spi1 {spi_demo: spi-demo00{status "okay";compatible "firefly,rk3399-spi";reg <0x00>;spi-max-frequency <48…

哈希思想的应用:位图、布隆过滤器及哈希切割

一.位图引入 给40定亿个不重复的无符号整数存储在文件中&#xff0c;如何判断一个数在不在其中&#xff1f; 分析&#xff1a;最容易想到的思路是将这些数字存储到某个能够实现快速查找的容器中&#xff0c;如红黑树或哈希表。 但是&#xff0c;10亿个字节大约占1G内存&#x…

使用JDBC操作数据库时,插入数据中文乱码

如图&#xff1a; 解决办法&#xff1a; 修改连接数据库的路径&#xff0c;即url 如下&#xff1a; 设置编码格式为utf-8 urljdbc:mysql://localhost:3306/qfedu?useUnicodetrue&characterEncodingUTF-8再次运行&#xff0c;插入数据即可