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

Linux 基础IO(上)--文件与文件描述符fd

 前言:

在生活里,我们常和各种文件打交道,像用 Word 写文档、用播放器看视频,这些操作背后都离不开文件的输入输出(I/O)。在 Linux 系统中,文件 I/O 操作更是复杂且关键。

接下来我们将深入探讨Linux 基础 IO,不仅包含了 C 语言文件 I/O 操作函数,如打开文件的fopen、读取文件的fread等常见接口,还详细讲解了系统文件 I/O 的函数和原理,以及文件描述符、重定向、缓冲区等重要概念(内容太多了,分成两篇博客介绍)。


目录

 前言:

一. 文件

       1.相关概念

            1.0 理解文件

           1.1文件组成:

            1.2文件路径:

            1.3文件访问:

             1.4进程与文件关系: 

​编辑

            1.5文件管理机制:

 2.系统调用接口

2.0 回顾C语言的函数接口

        2.01 从文件的打开到文件的关闭

       打开文件:fopen()

读取文件:fread()

文件修改:fwrite()

关闭文件:fclose()

       

         2.02 文件的错误处理

​编辑

2.03 默认的IO流 

 2.1. open,write,read,close函数:

           2.11 open函数

第一个参数pathname 

 第二个参数flags

第三个参数mode

open的返回值

2.2 write函数 

2.3 read函数

2.4close函数 

 三、文件描述符fd

3.1文件描述符的概念

3.2文件描述符与FILE*的区别

四.文件描述符fd分配规则

      4.1. 最小可用原则:

      4.2演示:


一. 文件

       1.相关概念

            1.0 理解文件

   狭义理解

  • 文件在磁盘里
  • 磁盘是永久性存储介质,因此文件在磁盘上的存储是永久性的(当然,时间久了肯定会有损害)
  • 磁盘是外设(即是输出设备也是输入设备,有文件从内存里读,就有文件向内存里写)
  • 对磁盘上所有文件的操作本质都是内存对外设的输入和输出,简称IO

   广义理解

  • 操作系统内一切皆文件
  • 操作系统为了方便管理各种各样的外设,选择将他们都看成文件便于管理。

           1.1文件组成:

                文件由属性和内容构成。

对于OKB的空文件是占用磁盘空间的,这是为啥呢???

大家可以想一想,我们平常在文件管理器上看到的KB大小,是不是指的文件大小,如果大小为0,为啥还会占用空间呢?很简单,磁盘当中存储的是我们文件的属性和内存,即使是空文件他还是要有文件本身的属性的。空文件在磁盘当中,存储的是文件的属性。

所以 文件=属性+内容


            1.2文件路径:

                (关于这一点我们在fopen那里会进一步讲解) 

                标定文件的唯一性需使用绝对路径(路径+文件名),未指定路径时默认当前目录。


            1.3文件访问:

                只有被打开的文件才能被进程访问,未被打开的文件存储在磁盘中。(后一部分   由文件系统管理,在下一篇博客中会专门讲解)


             1.4进程与文件关系: 

                        文件操作的本质是进程与被打开文件间的交互,由操作系统管理。多文件管理则是操作系统通过 `files_struct`统一 管理打开的文件,其中包含文件描述符表(fd数组),fd是数组索引。

就如图所示,每一个被打开的文件,操作系统都会分配一个file_struct的结构,管理并存储对应文件的属性与内容,而进程则是在PCB当中保存着一个可以指向被打开文件数组的指针,然后通过特定文件描述符访问或修改文件。


            1.5文件管理机制:

                        操作系统通过“先描述再组织”管理文件,内核中每个文件对应一个数据结构(`struct file`),包含文件属性和内容指针。

正如在1.4所说的,文件被操作系统用file_struct管理起来,如何管理不就是通过各种数据结构简单而高效的管理吗?这就是“再组织”的过程。通过对文件的结构的管理,不就实现了对文件的管理吗。


 2.系统调用接口

2.0 回顾C语言的函数接口

在C语言中,文件I/O操作主要是通过C语言的标准库提供的FILE *指针和一系列文件操作函数来实现的。这些函数为开发人员提供了更高层的文件操作接口,使得文件读写变得简单和方便。

        2.01 从文件的打开到文件的关闭
       打开文件:fopen()

  • filename:表示文件的路径,文件可以是相对路径或绝对路径。
  • mode:文件打开的模式,决定文件的读写方式。
  • 返回值:该函数成功返回打开文件的指针,失败着返回NULL。

"r"以只读模式打开文件,文件必须存在。
"w"

以写模式打开文件,若文件已存在,且文件有内容,则文件会被清空。

没有文件,则创建文件。

"a"以追加模式打开文件,若文件不存在则会创建文件。
"rb"以二进制模式只读打开文件,文件必须存在。
"wb"以二进制模式写入文件,若文件已存在则会被清空。

代码示例

  1 #include<stdio.h>2 #include<unistd.h>3 4 5 int main()6 {7   FILE* pf=fopen("text.txt","w");8   if(pf)9     printf("创建文件成功\n");                                                                     10   return 0;11 }
~

 结果

读取文件:fread()
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • ptr:指向内存的指针,用于存储读取的数据。
  • size:每个数据元素的大小(单位:字节)。
  • count:读取的元素个数。
  • stream:文件指针,指定从哪个文件读取数据。
  • 返回值:返回读取成功的字节个数

代码及结果

  1 #include<stdio.h>2 #include<unistd.h>3 4 5 int main()6 {7   FILE* pf=fopen("text.txt","r");8   if(!pf)9   {10     perror("open file failed:\n");11     return 99;12   }13     printf("打开文件成功\n");14     char buffer[100];15     size_t n=fread(buffer,sizeof(char),100,pf);16     if(n)                                                                                         17     {18       printf("读取成功\n");19       //之所以把数组的最后置成'\0',那是因为C语言的接口只能识别以’\0‘为结尾的字符串。20       buffer[n]='\0';21       printf("这是text.txt文件的内容:%s\n",buffer);22     }23   return 0;24 }

文件修改:fwrite()
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
  • ptr:指向内存中数据的指针。
  • size:每个数据元素的大小(单位:字节)。
  • count:写入的元素个数。
  • stream:文件指针,指定将数据写入哪个文件。 

    代码演示

      1 #include<stdio.h>2 #include<unistd.h>3 4 5 int main()6 {7 8   FILE* pf=fopen("text.txt","r");9   if(!pf)10   {11     perror("open file failed:\n");12     return 99;13   }14     printf("打开文件成功\n");15     char buffer[100]={"这是一段用于演示的代码,验证fwrite的功能\n"};16     size_t n=fwrite(buffer,sizeof(char),100,pf);17     if(n)18     {19       printf("读取成功\n");20       //之所以把数组的最后置成'\0',那是因为C语言的接口只能识别以’\0‘为结尾的字符串。21       buffer[n]='\0';22       printf("这是text.txt文件的内容:%s\n",buffer);23     }24   return 0;25 } 

    结果

    注:fwrite 函数本身既不是覆盖写也不是追加写,它的写入方式取决于文件的打开模式(是由'r'还是'w'决定的)。

    关闭文件:fclose()
    int fclose(FILE *fp);
    • fp:一个已经打开的文件指针 

    代码示例

    结果

           
             2.02 文件的错误处理

              在文件操作中,对于错误的处理是非常重要,C语言提供了两个函数来帮助开发者检测错误:ferror()feof()

    ferror()与feof()

     int feof(FILE *stream);int ferror(FILE *stream);
    
    • ferror(FILE *stream):判断是否发生了文件I/O错误。
    • 函数返回值:无错误出现时返回0;有错误出现时,返回一个非零值。
    • feof(FILE *stream):判断文件是否到达了末尾。
    • 函数返回值:如果没有到文件尾,返回0;到达文件尾,返回一个非零值。

    这两个错误处理的函数,主要是判断文件错误的类型。


    2.03 默认的IO流 

    都说Linux下一切皆文件,也就是说Linux下的任何东西都可以看作是文件(至少在操作系统看来),那么显示器和键盘当然也可以看作是文件。我们能看到显示器上的数据,是因为我们向“显示器文件”写入了数据,内存能获取到我们敲击键盘时对应的字符,是因为内存从“键盘文件”读取了数据。

    那么不有一个问题吗?文件的打开不是要进程主动打开使用吗?那为什么我们向“显示器文件”写入数据以及从“键盘文件”读取数据前,不需要进行打开“显示器文件”和“键盘文件”等相应操作?

    那自然是操作系统为我们打开了基础文件,任何进程在运行的时候都会默认打开三个输入输出流文件,即标准输入、标准输出以及标准错误,对应到C语言当中就是stdin、stdout以及stderr。

    查阅man手册

        extern FILE *stdin;extern FILE *stdout;extern FILE *stderr;
    

     当我们的C程序被运行起来时,操作系统就会默认使用C语言的相关接口将这三个输入输出流打开,之后我们才能调用类似于scanf和printf之类的函数向键盘和显示器进行相应的输入输出操作。

    当然在默认的情况下,stdout,stderr对应的外设都是显示器,stdin则是键盘。

    代码演示

    1 #include<unistd.h>2 #include<sys/types.h>3 #include<stdio.h>4 5 6 int main()7 {8   fclose(stdout);                                                                                                                                                                                            9   printf("这是一段用于演示,关闭标准输出流后,无法向显示器打印\n");10   return 0;11 }
    

    结果

     其实不止是C语言当中有标准输入流、标准输出流和标准错误流,C++当中也有对应的cin、cout和cerr,其他所有语言当中都有类似的概念。

    这也揭示了这种特性并不是某种语言所特有的,而是由操作系统所支持的。


     2.1. open,write,read,close函数:

            操作文件除了C语言接口、C++接口或是其他语言的接口外,操作系统也有一套系统接口来进行文件的访问。(各个语言对文件的访问,本质上都是对系统接口封装)。

    我们在Linux平台下运行C代码时,C库函数就是对Linux系统调用接口进行的封装,

    在Windows平台下运行C代码时,C库函数就是对Windows系统调用接口进行的封装,

    这样做使得语言有了跨平台性,也方便进行二次开发。

    (在不同的编译环境当中,C语言的库编写方式不同,因此在语言库的方面上保证C语言的可移植性)。

               2.11 open函数

                 man手册原型

     1 int open(const char *pathname, int flags);2 int open(const char *pathname, int flags, mode_t mode);
    

            参数分析
             

    • pathname:要打开的文件的路径。
    • flags:文件打开模式,决定文件的访问方式。
    • mode:文件权限,通常在文件创建时使用。
    第一个参数pathname 

    若pathname以路径的方式给出,则当需要创建该文件时,就在pathname路径下进行创建。
    若pathname以文件名的方式给出,则当需要创建该文件时,默认在当前路径下进行创建。(注意当前路径的含义) 

    还记得我们在“1.3文件路径”中所说的区别 

    什么是当前路径?
    我们知道,当fopen以写入的方式打开一个文件时,若该文件不存在,则会自动在当前路径创建该文件,那么这里所说的当前路径指的是什么呢?

    我们通过代码来验证一下

    代码

    1 #include<stdio.h>2 #include<unistd.h>3 4 5 int main()6 {7   FILE* pf=fopen("cwd.txt","w");                                                                  8   fclose(pf);9   return 0;10 }

    结果

    这是我们处于“cwd.exe”进程的相同的路径,结果与预想的差不多

    那是否意味着这里所说的“当前路径”是指“当前可执行程序所处的路径”呢?
    , 但如果我们处于与进程不同的路径下再次运行程序结果会如何呢??

    我们返回上级路径在测试一遍 

    这时我们可以发现,该可执行程序运行后并没有在FileIO目录下创建cwd.txt,而是在我们当前所处的路径下创建了cwd文本。

    为了解释这一现象,我们调出该进程的各项属性

    我们可以发现两个明显像是路径的变量,cwd就是进程运行时我们所处的路径,而exe就是该可执行程序的所处路径 

    总结: 实际上,我们这里所说的当前路径不是指进程运行时所处的路径,而是指该进程运行时我们所处的路径。


     第二个参数flags

    常见的flags参数包括:

    标志描述
    O_RDONLY以只读模式打开文件
    O_WRONLY以只写模式打开文件
    O_RDWR以读写模式打开文件
    O_CREAT文件不存在时创建文件
    O_TRUNC如果文件已存在,清空文件内容
    O_APPEND以追加模式打开文件

    在C语言中我们经常用一个整形来传递选项,但是如果如果选项较多时,就会造成空间的浪费,这里我们可以通过使用一个比特位表示一个标志位,这样一个int就可以同时传递至少32个标志位,此时的flag就可以看待成位图的数据类型。而上面的参数就是一个又一个不同位置的宏,代表的是不同的位。

    在打开文件的时候,利用“open”函数也可以达到“fopen”的效果,但是如果想要改变访问文件的方式就得利用flag参数。

    代码:

     1 #include<unistd.h>2 #include<stdio.h>3 #include <sys/types.h>4 #include <sys/stat.h>5 #include <fcntl.h>6 #include<string.h>7 8 9 int main()10 {11   int fd=open("open.txt",O_WRONLY | O_CREAT ,0664);12   if(fd == -1)13   {14     perror("open file falied\n");15     return -1;16   }17 18   const char str[]="这是一段用于检测open函数参数的示例\n";                                                                                                                                                   19   write(fd,str,sizeof(str));20   return 0;21 }
    

    结果

    第三个参数mode

    利用open函数的mode参数,可以对创建的文件进行权限管理,如果打开的文件已存在,那么该参数也无需去专门设置,设为0就好,但是不能不设置,否则会出现文件的权限错误。

    例如,将mode设置为0666,则文件创建出来的权限如下:

    按照之前的权限理解,我们创建的文件应该是具有所以的读写执行权限的。

    但实际上创建出来文件的权限值还会受到umask(文件默认掩码)的影响,实际创建出来文件的权限为:mode&(~umask)。umask的默认值一般为0002,当我们设置mode值为0666时实际创建出来文件的权限为0664。

    若想创建出来文件的权限值不受umask的影响,则需要在创建文件前使用umask函数将文件默认掩码设置为0。
    当然我并不建议对系统默认的值进行太多的修改。

    open的返回值

    open函数的返回值是新打开文件的文件描述符。

    当然啥是文件描述符在第三部分会有专门的介绍。


    2.2 write函数 

    接口

    1 #include <unistd.h>2 ssize_t write(int fd, const void *buf, size_t count);
    

     man手册

    参数分析

    • fd:文件描述符。
    • buf:指向的是要写入数据的内存空间。
    • count:要写入的字节数。

    我们可以使用write函数,将buf位置开始向后count字节的数据写入文件描述符为fd的文件当中。

    • 如果数据写入成功,实际写入数据的字节个数被返回。
    • 如果数据写入失败,-1被返回。

    演示:

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<string.h>int main()
    {int fd=open("Write.txt",O_WRONLY | O_CREAT,0666);if(fd < 0){perror("open");return 1;}const char* message ="Hello world 0.6\n";for(int i=0;i<10;i++)write(fd,message,strlen(message));return 0;
    }

    注:在上面的例子当中,我们不能使用sizeof函数充当write的第三个参数,因为message是一个指针,它不是一个字符数组。 

    注: 向文件写入数据时,是先将数据写入到对应文件的缓冲区当中,然后定期将缓冲区数据刷新到磁盘当中

    2.3 read函数

    接口:read():读取文件

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t count);

    man手册

    • 参数

      • fd:文件描述符(由 open 返回)。

      • buf:数据读取的缓冲区地址。

      • count:期望读取的字节数。

    • 返回值:实际读取的字节数(可能小于 count),0 表示文件结束,-1 表示错误。

    演示:

      1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/stat.h>5 #include<fcntl.h>6 #include<unistd.h>7 #define SIZE 10248 9 int main()10 {11         int fd=open("Write.txt",O_RDONLY,0666);12         if(fd < 0)13         {14                 perror("open failed:\n");15                 return 1;16         }17         char message[1024];18         ssize_t n=read(fd,message,sizeof(message));19         printf("这是读取到的数据:%s",message);20         return 0;21 }

     

    2.4close函数 

    接口:close()

    1 #include <unistd.h>
    2 int close(int fd);
    • 参数:要关闭的文件描述符。

    • 返回值:0 成功,-1 失败。

    当然这个函数是在是太简单了,这里就不在赘述。

    演示: 

      1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/stat.h>5 #include<fcntl.h>6 #include<unistd.h>7 #define SIZE 10248 9 int main()10 {11         int fd=open("Write.txt",O_RDONLY,0666);12         if(fd < 0)13         {14                 perror("open failed:\n");15                 return 1;16         }17         char message[1024];18         ssize_t n=read(fd,message,sizeof(message));19         printf("这是读取到的数据:%s",message);20         close(fd);21         return 0;22 }


     三、文件描述符fd

    3.1文件描述符的概念

    文件是由进程运行时打开的,一个进程可以打开多个文件,而系统当中又存在大量进程,这就导致了,在系统中任何时刻都可能存在大量已经打开的文件。
    因此,操作系统务必要对这些已经打开的文件进行管理,操作系统会为每个已经打开的文件创建各自的struct file结构体,然后将这些结构体以双链表的形式连接起来,之后操作系统对文件的管理也就变成了对这张双向链表的增删查改的操作。而在我们学习过进程相关概念后,我们也明白进程之间也是存在一个PCB结构体的。
    而为了区分已经打开的文件哪些属于特定的某一个进程,我们就还需要建立进程结构体和文件结构体之间的对应关系。

    进程和文件之间的对应关系是如何建立的?

     我们知道,当一个程序运行起来时,操作系统会将该程序的代码和数据加载到内存,然后为其创建对应的task_struct、mm_struct、页表等相关的数据结构,并通过页表建立虚拟内存和物理内存之间的映射关系。

    而task_struct当中有一个指针,该指针指向一个名为files_struct的结构体,在该结构体当中就有一个名为fd_array的指针数组(又被称为文件描述表),该数组的下标就是我们所谓的文件描述符。
    当进程打开log.txt文件时,我们需要先将该文件从磁盘当中加载到内存,形成对应的struct file,将该struct file连入文件描述符表,并将该结构体的首地址填入到fd_array数组当中下标为3的位置,使得fd_array数组中下标为3的指针指向该struct file,最后返回该文件的文件描述符给调用进程即可。

    这也是为啥文件描述符是一个整数,因为:它本质上是一个数组下标。

    3.2文件描述符与FILE*的区别

    虽然C语言提供了FILE *类型和相关的标准库函数来处理文件操作,但底层实际上是通过文件描述符来进行管理的。理解FILE *与文件描述符的区别对于深入理解文件I/O非常重要。

    1. 特性             FILE *(C标准库)                  文件描述符(Linux操作系统)
    2. 类型            由C标准库提供的类型                 操作系统内核使用整数值标识
    3. 管理者         由C标准库管理                           由操作系统内核管理
    4. 主要用途     提供更高级别的文件操作接口     提供更低级别的文件操作接口
    5. 缓冲区管理  提供缓冲区管理,提高效率        不提供缓冲区管理
    6. 数据访问方式 适用于文本文件的高级操作      适用于二进制文件和直接内存映射操作

    四.文件描述符fd分配规则


          4.1. 最小可用原则:

                    新打开的fd选择当前未被使用的最小整数【如关闭fd (0)后新文件占用0】。

          4.2演示:

      1 #include<stdio.h>2 #include<unistd.h>                                                                                           3 #include<sys/types.h>                                                                                        4 #include<sys/stat.h>                                                                                       5 #include<fcntl.h>                                                                                          6 #include<unistd.h>7 8 int main()9 {10         int fd1=open("Write.txt",O_RDONLY,0666);11         printf("这是关闭其他文件描述符之前的fd:%d\n",fd1);12         close(0);13         close(fd1);14         close(2);15         int fd2=open("Write.txt",O_RDONLY,0666);16         printf("这是关闭其他文件描述符之后的fd:%d\n",fd2);17         return 0;18 }

    解释:
    先打开一个文件,发现该文件的描述符是3【也很好理解,毕竟上面还有标准输入/输出/错误3者】,然后关闭标准输入、标准错误与该文件描述符【不关闭二,是我们后面还要打印fd观察现象】 ,在打开文件,发现描述符fd变成了0。

    相关文章:

    Linux 基础IO(上)--文件与文件描述符fd

    前言&#xff1a; 在生活里&#xff0c;我们常和各种文件打交道&#xff0c;像用 Word 写文档、用播放器看视频&#xff0c;这些操作背后都离不开文件的输入输出&#xff08;I/O&#xff09;。在 Linux 系统中&#xff0c;文件 I/O 操作更是复杂且关键。 接下来我们将深入探讨…...

    泛微OA.E9--07--IDEA搭建后端二开环境

    泛微OA.E9–07–IDEA搭建后端二开环境 一.前期准备 1.安装IDEA 2.从服务器中把ecology和JDK这几个文件拷贝到本地。 &#xff08;ecology太大的话可以不拷log日志文件&#xff09; 3.拷到本地后&#xff0c;在ecology文件下创建src文件夹 二.配置IDEA 1.启动IDEA后&#xff0…...

    美的人形机器人即将投入实际应用

    国内家电巨头美的集团近日公布了其自主研发的人形机器人的具体落地计划。根据公司披露的信息&#xff0c;这款机器人将于5月在湖北荆州的洗衣机工厂率先投入使用&#xff0c;承担设备运维、质量检测和物料搬运等工作任务。预计今年下半年&#xff0c;该机器人还将进入美的线下门…...

    【使用小皮面板 + WordPress 搭建本地网站教程】

    &#x1f680; 使用小皮面板 WordPress 搭建本地网站教程&#xff08;快速上手&#xff09; 本教程将手把手教你如何使用 小皮面板&#xff08;XAMPP 类似工具&#xff09; 和 WordPress 搭建一个完全本地化的网站环境。适合 初学者 / 博主 / Web开发者 本地练习使用&#xf…...

    EWM 流程全自动化实现方法

    目录 1 简介 2 实现方法 2.1 EWM 内向交货单自动创建 2.2 EWM 自动收货 2.3 当 EWM GR 的时候,自动触发 EWM 上架仓库任务。 2.4 确认 EWM 仓库任务/订单 3 写在最后 1 简介 当仓库遇到 EWM 的时候,大家首先想到的是 EWM 的业务操作多且功能复杂,甚至有些客户还会考…...

    智能驾驶新时代:NVIDIA高级辅助驾驶引领未来出行安全

    智能驾驶新时代&#xff1a;NVIDIA高级辅助驾驶引领未来出行安全 在全球汽车产业数字化转型的时代潮流中&#xff0c;高级辅助驾驶技术已逐渐成为推动产业革新的核心动力。作为这一领域的领导者之一&#xff0c;NVIDIA通过其先进的技术解决方案&#xff0c;正在积极塑造未来的…...

    NVIDIA DRIVE AGX平台:引领智能驾驶安全新时代

    随着科技的不断进步&#xff0c;汽车行业正迎来前所未有的变革&#xff0c;智能驾驶技术成为全球产业竞相布局的焦点之一。然而&#xff0c;这场技术革命的背后&#xff0c;最关键且被广泛关注的是安全性问题。近日&#xff0c;我认真研读了NVIDIA发布的《自动驾驶安全报告》白…...

    聚焦数字中国|AI赋能与安全守护:Coremail引领邮件办公智能化转型

    4月28日&#xff0c;第八届数字中国建设峰会在福州拉开序幕。当天&#xff0c;数字中国新产品新技术发布会开讲&#xff0c;Coremail受邀亮相现场&#xff0c;与与会嘉宾分享AI在邮件产品领域的最新应用成果和实践经验。 Coremail首席客户代表刘子建以《AI赋能与安全守护&#…...

    OpenCV的grabCut算法分割图像

    OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 基本概念 使用grabCut算法可以用最小程度的用户交互来分解前景。从用户角度来看&#xff0c;grabCut算法是怎么工作的呢&#xff1f;首先画一个矩形方块把前景图圈起来&#xff0c;前景区域应该完全在矩形内…...

    [计算机科学#6]:从锁存器到内存,计算机存储的构建与原理

    【核知坊】&#xff1a;释放青春想象&#xff0c;码动全新视野。 我们希望使用精简的信息传达知识的骨架&#xff0c;启发创造者开启创造之路&#xff01;&#xff01;&#xff01; 内容摘要&#xff1a;在上一篇文章中&#xff0c;我们深入了解了计算机如…...

    练习001

    目录 前言 数字诗意 分析 代码 封闭图形个数 分析 代码 回文数组 分析 代码 商品库存管理 分析 代码 挖矿 分析 代码 回文字符串 分析 代码 前言 好久不更新了&#xff0c;今天来更新一下。 当然不是主包偷懒啊&#xff0c;是最近的事情实在是有点多QAQ。…...

    【Linux调整FTP端口】

    Linux调整FTP端口 一、确保新端口未被占用在修改端口之前&#xff0c;可以使用以下命令检查端口是否被占用&#xff1a; 二、修改vsftpd配置文件1. 打开vsftpd配置文件2. 找到并修改端口配置3. 保存并退出4. 重启vsftpd服务 三、配置防火墙 在Linux系统中修改FTP端口&#xff0…...

    spring中的@Configuration注解详解

    一、概述与核心作用 Configuration是Spring框架中用于定义配置类的核心注解&#xff0c;旨在替代传统的XML配置方式&#xff0c;通过Java代码实现Bean的声明、依赖管理及环境配置。其核心作用包括&#xff1a; 标识配置类&#xff1a;标记一个类为Spring的配置类&#xff0c;…...

    AI中常用概念的理解

    1. RAG&#xff08;检索增强生成&#xff09; 通俗理解&#xff1a;就像你写作业时&#xff0c;先查课本 / 百度找资料&#xff0c;再根据资料写答案&#xff0c;而不是纯靠记忆瞎编。 AI 模型&#xff08;比如 ChatGPT&#xff09;回答问题时&#xff0c;先去 “数据库 / 互联…...

    JWT GenTokenParseToken

    JWT(Json Web Token) 获取Token、解密Token jwt.go package jwtimport ("errors""time""github.com/golang-jwt/jwt/v5" )var jwtSecret []byte("secret")type CustomClaims struct {Username string json:"username"jw…...

    ROS:发布相机、IMU等设备消息主题

    文章目录 📚简介📷发布相机消息主题🌐网络相机🚀RTSP🔌串口设备🧩 踩坑📚简介 使用ROS系统录制rosbag包,需要发布设备消息主题,才能使用rosbag record命令录制rosbag包。 📷发布相机消息主题 获取相机视频流的方式有多种,主要包含: 网络相机,使用RTSP…...

    C++好用的打印日志类

    在项目中,调试打印十分重要,这里分享一个自己写的简单但是实用的打印日志类,控制台打印时间戳具体内容保存文件 1.相关库介绍及其基本用法 a.<iostream> 功能&#xff1a;提供基本的输入输出流功能&#xff0c;如std::cout用于控制台输出&#xff0c;std::cin用于控制台输…...

    晶振:从消费电子到航天领域的时间精度定义者

    从手表到卫星&#xff1a;晶振如何在不同领域定义时间精度 在时间的长河中&#xff0c;人类对时间精度的追求永无止境。从古老的日晷到如今精密的计时仪器&#xff0c;每一次进步都离不开技术的革新。而晶振&#xff0c;作为现代计时的核心元件&#xff0c;在不同领域发挥着至…...

    huggingface下载数据和模型,部分下载,本地缓存等常见问题踩坑

    huggingface 注&#xff1a;系统环境为windows11 23H2&#xff0c;macOS和Linux用户可以查看下【参考】里的链接文档&#xff0c;差异不大 安装huggingface-cli 虽然可以通过代码下载模型和数据集&#xff08;下文会提及&#xff09;&#xff0c;但我依然推荐你用此方法来管理…...

    分布式架构:Dubbo 协议如何做接口测试

    传统单体架构是一个应用程序进程内处理完所有的逻辑&#xff1a;一个系统糅合了多个功能&#xff0c;如注册 --登录–充值–余额管理–用户积分等&#xff0c;所有的功能模块都是在一个应用程度里处理完的&#xff1b;一个请求过来–> 到应用程序系统–>数据库处理–>…...

    Python math 库教学指南

    Python math 库教学指南 一、概述 math 库是 Python 标准库中用于数学运算的核心模块&#xff0c;提供以下主要功能&#xff1a; 数学常数&#xff08;如 π 和 e&#xff09;基本数学函数&#xff08;绝对值、取整等&#xff09;幂与对数运算三角函数双曲函数特殊函数&…...

    Antd Upload组件连续回车会多次触发文件夹弹窗的bug修复

    看了看issue一大堆&#xff0c;没一个解决的&#xff0c;真恼火&#xff1a;Upload 上传组件&#xff0c;当上传完一个文件后&#xff0c;我按下键盘回车键&#xff0c;自动又打开了“选择文件窗口”&#xff0c;点击“选择文件窗口”下面的取消按钮&#xff0c;再次打开了“选…...

    数据仓库与数据湖的对比分析

    目录 一、数据来源 数据仓库 数据湖 二、数据模式转换时机 数据仓库 数据湖 三、数据存储成本 数据仓库 数据湖 四、数据质量 数据仓库 数据湖 五、面向用户 数据仓库 数据湖 六、主要支撑的应用类型 数据仓库 数据湖 在企业数据管理领域&#xff0c;数据仓库…...

    Windows系统下MinerU的CUDA加速配置指南

    Windows系统下MinerU的CUDA加速配置指南 快速解锁GPU性能,提升文档解析效率 1、简介 MinerU是一款高效的文档解析工具,支持通过CUDA加速显著提升处理速度。本指南详细说明如何在Windows系统中配置CUDA环境,并启用MinerU的GPU加速功能,帮助用户充分利用NVIDIA显卡的计算能…...

    LeetCode路径总和系列问题解析:I、II、III的解决方案与优化

    文章目录 引言一、路径总和 I&#xff08;LeetCode 112&#xff09;问题描述方法思路Java代码实现复杂度分析 二、路径总和 II&#xff08;LeetCode 113&#xff09;问题描述方法思路Java代码实现复杂度分析 三、路径总和 III&#xff08;LeetCode 437&#xff09;问题描述方法…...

    【漫话机器学习系列】233.激活阈(Threshold Activation)

    深度学习入门&#xff1a;了解“阈值激活函数”&#xff08;Threshold Activation Function&#xff09; 激活函数是神经网络中至关重要的一环。今天&#xff0c;我们通过一幅简单直观的手绘图&#xff0c;一起理解最早期也最基础的激活函数之一 —— 阈值激活函数&#xff08;…...

    使用vue开发electron

    1.全局安装electron npm i electron -g 查看是否安装成功 electron -v 在vue项目中添加electron模块 vue add electron-builder 添加成功后&#xff0c;目录中多了background.js文件 可以在background.js配置 例如 窗口大小&#xff0c;是否可以缩放&#xff0c;是否可以移…...

    安全企业内部im,BeeWorks即时通讯

    BeeWorks企业即时通讯软件具备哪些优势&#xff1f; 1. 多样的沟通方式 文本消息&#xff1a;支持发送文字消息&#xff0c;包括富文本格式&#xff08;如加粗、斜体、下划线、颜色等&#xff09;。 语音消息&#xff1a;支持发送语音消息&#xff0c;方便快捷&#xff0c;适…...

    网易爆米花 1.8.8 | 免费无广告,支持多网盘聚合和智能刮削技术,提供顶级画质和逼真音效的影视管理应用

    网易爆米花TV是一款专为家庭设计的影视管理应用&#xff0c;旨在提供一个简洁易用的家庭影视库。它支持从多个网盘&#xff08;如阿里、百度、天翼等&#xff09;、WebDAV以及本地资源导入&#xff0c;聚合用户的影视资源&#xff0c;并通过智能刮削技术将视频信息形成精美的影…...

    蓝牙语音遥控国产适用芯片HS6621

    蓝牙语音遥控器一般是通过按下语音键&#xff0c;遥控器会发送一个 HID 编码通知智能电视或者机顶盒打开识音功能&#xff0c;此时&#xff0c;遥控器LED灯保持闪烁或者长亮&#xff0c;用户开始录音同时将语音数据上传给智能电视或者机顶盒。而智能电视或者机顶盒&#xff0c;…...

    【Vue2】1-创建一个Vue实例

    Vue2官方文档 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&g…...

    销售与金融领域的数据处理与分析方法

    一、引言 在销售和金融领域&#xff0c;除了常见的同比、环比和移动平均等数据处理方法外&#xff0c;还有众多方法可供选择&#xff0c;这些方法分布于不同的专业方向&#xff0c;旨在帮助分析和解决问题&#xff0c;以下将按类别对这些方法进行详细梳理。 二、按类别划分的…...

    DataWorks Copilot 集成 Qwen3-235B-A22B混合推理模型,AI 效能再升级!

    刚刚&#xff0c;阿里云一站式智能大数据开发治理平台 DataWorks 正式接入 Qwen3 模型&#xff0c;可支持235B最大尺寸。用户通过 DataWorks Copilot 智能助手即可调用该模型&#xff0c;通过自然语言交互完成多种代码操作&#xff0c;实现数据开发、数据分析的快速实现。 Qwen…...

    芯片软错误概率探究:基于汽车芯片安全设计视角

    摘要&#xff1a; 本文深入剖析了芯片软错误概率问题&#xff0c;结合 AEC-Q100 与 IEC61508 标准&#xff0c;以 130 纳米工艺 1Mbit RAM 芯片为例阐述其软错误概率&#xff0c;探讨汽车芯片安全等级划分及软错误对汽车关键系统的影响&#xff0c;分析先进工艺下软错误变化趋势…...

    青少年抑郁症患者亚群结构和功能连接耦合的重构

    目录 1 研究背景及目的 2 研究方法 2.1 数据来源与参与者 2.1.1 MDD患者&#xff1a; 2.1.2 健康对照组&#xff1a; 2.2 神经影像分析流程 2.2.1 图像采集与预处理&#xff1a; 2.2.2 网络构建&#xff1a; 2.2.3 区域结构-功能耦合&#xff08;SC-FC耦合&#xff09…...

    汽车OTA在线升级法规分析

    摘要 本文介绍了R156法规即《关于批准车辆的软件升级和软件升级管理体系统一规定的法规》、该法规专注于汽车软件升级功能&#xff0c;并为此提出了一系列具体要求&#xff0c;旨在确保软件升级流程的安全性、可控性和合规性&#xff0c;从而顺应汽车行业智能化、联网化的发展趋…...

    【上海大学数据库原理实验报告】MySQL基础操作

    实验目的 熟悉MySQL基础操作。 实验内容 创建四张工程项目的关系表。 图 1 四张工程项目关系表的结构 检索供应零件编号为J1的工程的供应商编号SNO。检索供应零件给工程J1&#xff0c;且零件编号为P1的供应商编号SNO。查询没有正余额的工程编号、名称及城市&#xff0c;结果…...

    FUSE 3.0.0 | 聚合7大直播平台的免费电视直播软件,支持原画清晰度及弹幕、收藏功能

    FUSE是一款第三方娱乐直播软件&#xff0c;它聚合了多个直播平台的内容&#xff0c;为用户提供丰富的观看选择。首次进入软件后点击左上角logo&#xff0c;然后点击‘我已诚信付款&#xff0c;解锁LIVEPRO’按钮即可解锁所有功能。该软件聚合了7大直播平台&#xff0c;每个平台…...

    在企业微信中,回调地址 redirect_uri 是允许包含端口号

    在企业微信中&#xff0c;回调地址&#xff08;redirect_uri&#xff09;允许包含端口号的原因主要有以下几点&#xff1a; 1. 企业微信的开放设计 企业微信对回调地址的校验相对灵活&#xff0c;允许开发者根据实际业务需求配置带端口号的域名。这与部分严格限制端口的平台&a…...

    Rust 学习笔记:枚举与模式匹配

    Rust 学习笔记&#xff1a;枚举与模式匹配 Rust 学习笔记&#xff1a;枚举与模式匹配定义枚举&#xff08;Enum&#xff09;枚举变量Option 枚举及其相对于 NULL 的优势match 和枚举与 Option\<T\> 匹配match 应该是详尽的Catch-all 模式和 _ 占位符使用 if let 和 let e…...

    UI自动化测试的优势

    1. UI自动化测试的优势(提升效率的场景) ✅ 适合自动化的场景 (1) 高频回归测试 典型场景:每次版本迭代都要验证的核心功能(如登录、支付流程)。 效率提升:自动化脚本执行速度远高于手动测试,尤其适合敏捷开发中的快速验证。 (2) 跨平台/多环境测试 典型场景:需要在不…...

    【Android】轻松实现实时FPS功能

    文章目录 实时FPS 实时FPS 初始化 choreographer Choreographer.getInstance();lastFrameTimeNanos System.nanoTime();choreographer.postFrameCallback(frameCallback);监听并显示 Choreographer.FrameCallback frameCallback new Choreographer.FrameCallback() {Overri…...

    BI平台是什么意思?一文讲清BI平台的具体应用!

    目录 一、BI平台是什么意思 1. 基本概念 2. 核心功能 3. 重要性 二、BI平台的分类 1. 按部署方式分类 2. 按功能特点分类 3. 按行业应用分类 三、BI平台的使用场景 1. 销售与营销分析 2. 财务分析 3. 人力资源管理 4. 供应链管理 5. 运营管理 总结 “BI 平台是什…...

    玩转MCP

    玩转MCP 0.环境1.自定义stdio交互1.1.server1.2.client1.3.效果 2.自定义sse交互2.1.server2.2.client2.3.效果 3.使用官方文件 mcp火了好一阵了&#xff0c;最近一直在大院干活儿&#xff0c;好不容易抽出时间&#xff0c;赶紧来学习学习。 官方文档&#xff0c; mcp广场可以…...

    2025华东杯A/B/C题解题思路+可运行代码参考

    A题:跳台滑雪问题 选题分析: 跳台滑雪问题涉及物理学、运动学和优化算法。需要建立数学模型来分析运动员在不同阶段的最佳姿势和策略,以提高运动成绩。问题分为三个小问,分别是助滑坡姿势、空中飞行控制和着陆策略。 解题思路: 1. 助滑坡姿势: 分析助滑坡的物理特性,…...

    IsaacLab最新2025教程(7)-创建Interactive Scene

    在isaaclab中创建的强化学习训练环境有两种&#xff1a;direct workflow&#xff0c;风格与isaacgym一样。另外一种是manager-based workflow更加模块化&#xff0c;它主要是两部分包括仿真环境也就是即将介绍的interactive scene&#xff0c;与mdp的内容&#xff0c;比如奖励函…...

    Linux远程管理

    1.网络管理获取计算机的网络信息基本语法&#xff1a;windows ipconfig<img src"ReadMe.assets/image-20250318152355476.png" alt"image-20250318152355476" style"zoom:33%;" />powershell ifconfig 也可以通过上面的网络处获取powershe…...

    双指针(4)——盛水最多的容器

    题目&#xff1a; 这题可以暴力枚举&#xff0c;但会超时&#xff0c;所以我们要用其他方法。 我们就用示例1的数组为例&#xff0c;我们先取出一部分研究。 虽然我们不能用暴力枚举&#xff0c;但可以借用其思想。 对于6和4组成的容器&#xff0c;它可以储存24个单位的水。…...

    sd webui 安装插件sd-webui-EasyPhoto依赖安装失败解决办法

    在最新版的SD webui中&#xff0c;可以安装easyphoto插件&#xff0c;官方建议通过github安装&#xff0c;对无法科学上网的用户很不友好。对我自己来说是通过地址&#xff1a; https://gitee.com/wowai/sd-webui-EasyPhoto.git 分支&#xff1a;anyid 点击安装即可。 在安装…...

    虚拟机对前端开发的实用价值:提升效率与解决痛点的完整指南

    作为前端开发者&#xff0c;虚拟机可能不是你日常工作的核心工具&#xff0c;但它确实能在多个方面为前端开发提供强大支持。下面我将详细解析虚拟机如何帮助前端开发者提升工作效率、解决开发难题。 一、跨浏览器/跨平台测试环境搭建 1.1 多浏览器测试 真实IE测试&#xff…...