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

【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:C语言进阶
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 1.文件操作
    • 1.1 概述:
      • 1.1.1 为什么使用文件:
      • 1.1.2 什么是文件:
        • ①.程序文件:
        • ②.数据文件:
        • ③.文件名:
  • 2. 文件顺序读写:
    • 2.1 文件的打开和关闭:
      • ①.文件指针:
      • ②.文件的打开与关闭:
      • ③.文件打开模式:
    • 2.2.文件的顺序读写:
  • 3. 文件随机读写:
    • 3.1 fseek 函数:
    • 3.2 ftell 函数:
    • 3.3 rewind 函数:
  • 4. 文本文件与二进制文件:
  • 5. 文件读取结束的判定:
    • 5.1 错误使用 feof 函数:
    • 5.2 判断文件读取结束:
  • 6. 文件缓冲区:
  • 7.总结:

1.文件操作

1.1 概述:

我们进行的所有操作都是在计算机内存中进行的,并且我们所操作的数据也是存放在计算机内存中的,一旦我们退出了程序,内存空间就会被释放并回收,而这个过程中我们所操作的所有的数据也将不复存在。如此,我们无法将数据真正保留下来,只能在每次运行程序时重新进行输入,重新录入信息,使用起来极为不便。

1.1.1 为什么使用文件:

我们希望将数据保留在本地,只有当我们进行删除操作时,才将对应的数据删除掉,即尝试实现数据的持久化。而我们实现数据持久化的方式一般有两种:使用数据库将数据存放至本地磁盘中。
目前还没有接触到数据库的知识,于是我们便通过学习文件操作,来将我们的数据存放至我们计算机的本地硬盘中,从而实现数据的持久化。

1.1.2 什么是文件:

我们通常所说的文件,一般是指存放在我们计算机本地硬盘上的文件。但是在我们的程序设计中(根据文件功能分类),指的是程序文件数据文件两种文件。

①.程序文件:

程序文件主要包括源程序文件、目标文件和可执行程序文件。

源程序文件(后缀为 .c)
目标文件( Windows 环境下后缀为 .obj)
可执行程序文件( Windows 环境下后缀为 .exe)

②.数据文件:

数据文件的内容不一定是程序,而是程序运行过程中所进行读写的数据,比如程序运行中需要从中读取的数据,或者程序运行完毕所输出的文件。
今天所讨论的,正是数据文件的相关操作
在前面所有内容的学习中,我们所有的输入输出,其操作对象都是终端,均为从键盘读取输入内容,并将处理结果输出致我们的计算据显示器上进行反馈。而今天我们的目的则是将数据信息输入至我们的本地磁盘上,当我们想要对数据进行操作时,便从本地硬盘进行读取。

③.文件名:

文件和我们人类有自己的名字一样,也需要有一个文件标识符,文件名的存在就是为了便于我们进行识别和引用。
而一个文件的文件名由三部分组成:文件路径 + 文件名主干 + 文件后缀

以文件名“ c:\code\test.txt ”为例:
文件路径为“ c:\code\ ”,表示文件存放在硬盘 C 盘下的 code 文件夹内。
文件名主干为“ test ”,表示该文件的文件名为 test。
文件后缀为“ .txt ”,表示该文件的文件类型为文本文件。

2. 文件顺序读写:

2.1 文件的打开和关闭:

我们在使用或操作我们的文件之前,首先需要在我们的程序中及将其打开

①.文件指针:

首先需要了解一下文件指针这个概念,这是因为不光是文件的打开与关闭,包括后面我们在对我们的文件进行操作时,也都是通过文件指针实现的。
在缓冲文件系统中,最关键的一个概念就是“ 文件类型指针 ”,即我们通常所说的“ 文件指针 ”。并且我们要知道,我们使用的每一个文件都在内存中开辟了相应的文件信息区,用于存放该文件的相关信息,并且这些信息都保存在一个结构体变量中。
并且这样的结构体类型是有系统声明的,取名为 FILE
例如在 Visual Studio 的头文件stdio.h中(非自定义结构体类型)就有该类型的声明:

struct _iobuf 
{char *_ptr;int   _cnt;char *_base;int   _flag;int   _file;int   _charbuf;int   _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;

使用不同的 C 语言编译器,FILE 类型中所包含的信息可能不完全相同,但是都大同小异。每当我们打开一个本地文件时,系统就会依据我们打开的文件的情况自动创建出一个 FILE 结构的变量,并填充该结构内的信息。而这个由系统创建出来并填充的 FILE 结构变量,就是通过一个 FILE 类型文件指针类进行调用和维护的。

FILE* p;
//定义一个文件指针p

像这样,我们就能创建出一个文件指针,而接下来就可以使这个文件指针 p 指向某个文件信息区(FILE 类型的结构体变量),并通过该文件信息区中所保存的信息来访问本地硬盘内的文件了。通过使用文件指针就可以找到与其相关联的文件了。

②.文件的打开与关闭:

应在读写文件之前打开文件,并在文件读写结束后关闭文件。同时ANSI C规定,使用 fopen 函数(file open)来打开文件,用 fclose 函数(file open)来关闭文件。

什么是ANSI C、ISO C、C89、C90标准?
随着C语言使用得越来越广泛,出现了许多新问题,人们日益强烈地要求对C语言进行标准化。1983年,美国国家标准协会(ANSI)组成了一个委员会,X3J11,为了创立C的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,这个版本的语言经常被称作ANSI C,或有时称为C89(为了区别C99)在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会(ANSI)采纳为ISO/IEC 9899:1990。这个版本有时候称为C90或者ISO C。综上,ANSI C、ISO C、C89、C90其实是同一种标准。

open 函数的使用方式为:

FILE* p = fopen(const char* filename, const char* mod);

1.其中“ const char* filename ”指文件名(是字符串,文件名即文件标识符)。
2.其中“ const char* mod ”指文件打开模式(也是字符串,后面会列出)

int main()
{//打开文件:FILE* p = fopen("test.txt", "r");//以"r",即只读模式打开文件c:\code\test.txt//默认路径为.c文件同目录下if (p == NULL)//判断文件打开是否成功{perror("FILEOPEN");//打开失败打印错误原因并退出return 1;}printf("success\n");return 0;
}

fclose 函数的使用方式为:

 fopen(FILE* strname);

“ FILE* strname ”指的是指向期望关闭文件的文件指针。
因为我们在打开文件时没有特意注明路径,则默认路径为 .c 文件的同目录下。为了验证我们代码的正确性,我们在该目录下创建“ test.c ”文件用于代码测试:
在这里插入图片描述

int main()
{//打开文件:FILE* p = fopen("test.txt", "r");//以"r",即只读模式打开文件c:\code\test.txtif (p == NULL)//判断文件打开是否成功{perror("FILEOPEN");//打开失败打印错误原因并退出return 1;}printf("open success\n");//验证文件是否成功打开fclose(p);p = NULL;if (p == NULL){printf("close success\n");//验证文件是否成功关闭}return 0;
}

在这里插入图片描述

③.文件打开模式:

请添加图片描述

2.2.文件的顺序读写:

请添加图片描述
这其中较为常用的就是 fputc 函数与 fgetc 函数,我们一般就通过这两个函数来实现对文件内容的顺序读写。
这两个函数的使用方式为:

fputc(const char charname, FILE* strname);
fget(FILE* strname);

首先文本文件 test.txt 中的内容为空,没有内容
接下来我们使用“ 写 ”模式打开该文件,并在判断非空后使用 fputc 函数来进行顺序写入:

int main()
{FILE* p = fopen("test.txt", "w");//文件打开模式为“写”if (p == NULL){perror("FILEOPEN");return 1;}char ch = 'a';for (ch = 'a'; ch <= 'z'; ch++){fputc(ch, p);//使用 fputc 函数顺序写入小写字符a~z}fclose(p);p = NULL;return 0;
}

我们等待程序编译运行并完成数据写入后关闭程序,这时我们来到本地文件中查看硬盘中本地文件的数据写入情况:
在这里插入图片描述
我们看到本地文件中的内容已经实现了数据的顺序写入。
完成后我们再用“ 读 ”模式打开该文件,并在判断非空后使用 fgetc 函数来顺序读取该文件中的内容:

int main()
{FILE* p = fopen("test.txt", "r");//文件打开模式为“读”if (p == NULL){perror("FILE_OPEN");return 1;}int ch = 0;while ((ch = fgetc(p)) != EOF){printf("%c ", ch);//顺序读取文件指针pp指向文件内的信息并打印}fclose(p);p = NULL;return 0;
}

将程序编译运行起来查看我们 fgetc 函数的读取结果:
在这里插入图片描述
并且我们也可以使用 fputs 函数(区别于 fputc 函数)来实现字符串的顺序写入:

int main()
{FILE* p = fopen("test.txt", "w");//文件打开模式为“写”if (p == NULL){perror("FILE_OPEN");return 1;}fputs("The test TXT\n", p);//fputc 为写入字符,fouts 为写入字符串//只写入字符串内容,不会自动换行,想要换行需手动添加换行转义字符\n//并且在写入时,会覆盖原本的内容数据fputs("The test TXT", p);fclose(p);p = NULL;return 0;
}

或使用 fgets 函数(区别于 fgetc 函数)来实现字符串的顺序读取:

int main()
{FILE* p = fopen("test.txt", "r");//文件打开模式为“读”if (p == NULL){perror("FILE_OPEN");return 1;}char arr[256] = { 0 };//定义字符数组用于存放读取到的字符串fgets(arr, 256, p);//从文件指针p指向文件处,读取最多256个字符,并将数据读取至字符数组arr中//该函数为按行读取,读取至换行转义符\n处主动停止并换行printf("%s", arr);//想要读取两行就需要使用两次fgets函数fgets(arr, 256, p);printf("%s", arr);fclose(p);p = NULL;return 0;
}

最终目的,就是要结合文件操作将数据保存至本地硬盘中,从而实现优化,于是我们可以使用 fprintf 函数实现将结构体变量的内容保存至本地硬盘之中:

typedef struct Contact
{char name[20];char sex[5];int age;char tele[11];
}con;
int main()
{FILE* p = fopen("test.txt", "w");//文件打开模式为“写”if (p == NULL){perror("FILE_OPEN");return 1;}con c1 = { "Sherry","女",18,"3478290" };fprintf(p, "%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele);//按照"%s %s %d %s\n"的格式将数据c1.name, c1.sex, c1.age, c1.tele写入至p所指向的文件内fclose(p);p = NULL;return 0;
}

程序编译运行结束后关闭,这时我们再去本地文件中查看会发现,数据已经成功的保存至本地硬盘中了:
在这里插入图片描述

并且我们也可以通过 fscanf 函数从本地硬盘文件中读取数据:

typedef struct Contact
{char name[20];char sex[5];int age;char tele[11];
}con;
int main()
{FILE* p = fopen("test.txt", "r");//文件打开模式为“读”if (p == NULL){perror("FILE_OPEN");return 1;}con c1 = { 0 };fscanf(p, "%s %s %d %s", c1.name, c1.sex, &(c1.age), c1.tele);//按照"%s %s %d %s"的格式,从p所指向的文件中将数据读取至c1.name, c1.sex, &(c1.age), c1.tele中printf("%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele);fclose(p);p = NULL;return 0;
}

在这里插入图片描述

3. 文件随机读写:

我们很多时候并不是要进行顺序读写,而是进行随机读写(伪随机,指不按照顺序依次进行读写)。为了实现这样的操作,我们就需要使用 fseekftellrewind 三个函数来帮助我们对这样的操作进行实现。

3.1 fseek 函数:

fseek 函数的作用为,根据文件指针的位置和偏移量来定位文件指针。

int fseek(FILE* strname, long int offset, int origin);

1.“ offset”为相对于指针位置的指针偏移量
2.“ origin ”为指针位置,其参数有三种:“ SEEK_CUR ”表示文件指针当前位置;“ SEEK_END ”表示文件末尾的位置;“ SEEK_SET ”表示文件开始位置。

int main()
{FILE* p = fopen("test.txt", "r+");//文件打开模式为“读写”if (p == NULL){perror("FILE_OPEN");return 1;}char ch = 'a';for (ch = 'a'; ch <= 'z'; ch++){fputc(ch, p);//使用 fputc 函数顺序写入小写字符a~z}fseek(p, 10, SEEK_SET);//使用fseek函数将文件指针从文件开始处(参数SEEK_SET表示文件起始位置)指向偏移量为10处//偏移量为正表示向后偏移,为负表示向前偏移char output;output = fgetc(p);//接下来进行读取时,继续向后读取一个字符,即字符kprintf("%c\n", output);fclose(p);p = NULL;return 0;
}

在这里插入图片描述

3.2 ftell 函数:

 long int ftell(FILE* strname);

ftell 函数的作用为,返回文件指针相对于文件起始位置的偏移量。

int main()
{FILE* p = fopen("test.txt", "r+");//文件打开模式为“读写”if (p == NULL){perror("FILE_OPEN");return 1;}char ch = 'a';for (ch = 'a'; ch <= 'z'; ch++){fputc(ch, p);//使用 fputc 函数顺序写入小写字符a~z}fseek(p, -5, SEEK_END);//使用fseek函数将文件指针从文件结尾处(参数SEEK_SET表示文件起始位置)指向偏移量为-5处//偏移量为正表示向后偏移,为负表示向前偏移long back = ftell(p);//定义整型变量用于接受并记录指针相对于起始位置的偏移量printf("指针相对于起始位置的偏移量为:%ld\n", back);fclose(p);p = NULL;return 0;
}

在这里插入图片描述

3.3 rewind 函数:

void rewind(FILE* strname);

rewind 函数的作用为,使文件指针位置返回文件的起始位置

int main()
{FILE* p = fopen("test.txt", "r+");//文件打开模式为“读写”if (p == NULL){perror("FILE_OPEN");return 1;}char ch = 'a';for (ch = 'a'; ch <= 'z'; ch++){fputc(ch, p);//使用 fputc 函数顺序写入小写字符a~z}fseek(p, -5, SEEK_END);rewind(p);//使文件指针回归文件起始位置printf("%c\n", fgetc(p));//打印验证指针当前位置fclose(p);p = NULL;return 0;
}

在这里插入图片描述

4. 文本文件与二进制文件:

根据数据的组织形式,我们将数据文件称为文本文件二进制文件
二进制文件:在我们的计算机内存中,各种数据都是以二进制码的形式进行存储的,以 二进制码形式进行存储的文件
文本文件:以 ASCII 字符形式进行存储的文件
如果我们想要在外存上以 ASCII 码的形式存储数据,就需要在存储前将数据进行转换
数据在内存中数据到底是如何让进行存储的呢?
实际上,字符在内存中的存储一律是以 ASCII 码的形式进行存储的,而数值型数据既可以用ASCII 码存储,也可以用二进制形式进行存储。

例如十进制数字 10000 在进行存储时,就可以有两种存储形式:
1.二进制形式:
00000000 00000000 00100111 00010000
2.ASCII码形式:
00110001 00110000 00110000 00110000 000110000
1 0 0 0 0


int main()
{int a = 10000;FILE* p = fopen("test.txt", "wb");//“wb”表示以只写模式打开二进制文件if (p == NULL){perror("FileOpen");return 0;}fwrite(&a, 4, 1, p);//将变量a中的数据,每四个字节存储一次,写入文件指针p所指向的文件fclose(p);p = NULL;return 0;
}

在上面这段代码运行成功后,我们已经成功的将变量 a 中的数据写入到了本地磁盘对应的 txt 文件中了,可是我们发现,当我们尝试打开本地文件查看存储的数据时,里面看起来并不是我们想要的结果:
在这里插入图片描述
是我们的程序哪里出错了吗?其实并不是,而是因为我们使用了" wb "方式,即以二进制形式进行了写入,所以我们在尝试直接查看时显示的是二进制符号。
所以我们就需要换一种方式才能对我们的文件内容进行查看。首先选中我们的“ 源文件 ”栏,右击选择“ 添加 ” -> “ 添加现有项 ”,将写入时创建的 txt 文件添加进来
在这里插入图片描述
然后选中 txt 文件,右击选择“ 打开方式 ”选项
在这里插入图片描述

接着在选项框中下拉选择“ 二进制编辑器 ”
在这里插入图片描述
这时我们就看到了文件内的实际存储情况了:

在这里插入图片描述

它显示我们的文件中的实际存储数据为 10 27 00 00,这又是怎么来的呢?这是因为,我们在存储时根据语句:

fwrite(&a, 4, 1, p);

根据这条语句,我们在进行数据写入时,是四个字节一组进行写入的,于是根据其二进制码可以得到它的存储为:

每四个字节进行划分:0000 0000 0000 0000 0010 0111 0001 0000
于是得到:00 00 27 10

又因为在之前我们就验证过我的计算机采用的是小端存储模式,于是在进行压栈时会将数据进行倒置存储,于是就有:

10 27 00 00

5. 文件读取结束的判定:

5.1 错误使用 feof 函数:

  1. 在文件的读取过程中,不能通过 feof 函数的返回值来判定文件是否读取结束。
  2. 该函数的作用为,在已经确定文件读取结束的情况下,用于判定文件读取结束的原因

5.2 判断文件读取结束:

如何正确判断文件是否读取结束?

文本文件判断文件读取结束方法:
①. 使用 fgetc 函数判断是否为 EOF
②. 使用 fgets 函数判断返回值是否为 NULL

#include<stdio.h>
#include<stdlib.h>
int main()
{int c; //注意:int,非char,要求处理EOFFILE* fp = fopen("test.txt", "r");if (!fp){perror("File opening failed");return 1;}// fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF)// 标准C I/O读取文件循环{putchar(c);}//判断是什么原因结束的if (ferror(fp)){puts("I/O error when reading");}else if (feof(fp)){puts("End of file reached successfully");}fclose(fp);fp = NULL;return 0;
}

二进制文件判断文件读取结束方法:
使用 fread 函数判断返回值是否小于实际要读取的数据个数。

#include<stdio.h>
enum {SIZE = 5
};
int main(void)
{double a[SIZE] = { 1.,2.,3.,4.,5. };FILE* fp = fopen("test.bin", "wb");//必须用二进制模式fwrite(a, sizeof * a, SIZE, fp);//写 double 的数组fclose(fp);double b[SIZE];fp = fopen("test.bin", "rb");size_t ret_code = fread(b, sizeof * b, SIZE, fp);//读 double 的数组if (ret_code == SIZE){puts("Array read successfully, contents: ");for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]);putchar('\n');}else {// error handlingif (feof(fp)){printf("Error reading test.bin: unexpected end of file\n");}else if (ferror(fp)){perror("Error reading test.bin");}}fclose(fp);fp = NULL;return 0;
}

在这里插入图片描述

6. 文件缓冲区:

文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。通过磁盘缓存来实现,磁盘缓存不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的存储空间, 来暂存从磁盘中读出 (或写入)的信息。
例如在国际 ANSI C 标准中,就是采用“ 缓冲文件系统 ”来对数据文件进行处理的。缓冲文件系统会自动地在我们的内存空间中为程序中的每个正在使用的文件开辟一块“ 文件缓冲区 ”。

计算机内存中向本地磁盘中输出数据:
将会先送至缓冲区->将缓冲区全部装满后->一并送达磁盘。
从磁盘向计算机读入数据:
从磁盘文件中读取数据->并将其输入至缓冲区->并在充满缓冲区后再逐个地将数据送达程序数据区

而至于缓冲区的大小,则是由 C 编译系统决定的
验证缓冲区:

#include <stdio.h>
#include <Windows.h>
//VS2022 WIN10环境测试int main()
{FILE* pf = fopen("test.txt", "w");fputs("abcdef", pf);//先将代码放在输出缓冲区printf("睡眠10秒\n");//已经写数据了,但是打开test.txt文件,发现文件没有内容Sleep(10000);printf("刷新缓冲区\n");fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)//注:fflush 在高版本的VS上不能使用了printf("再睡眠10秒\n");//此时,再次打开test.txt文件,文件有内容了Sleep(10000);fclose(pf);//注:fclose在关闭文件的时候,也会刷新缓冲区pf = NULL;return 0;
}

因为缓冲区的存在,数据只有在填满缓冲区后才会进行真正的写入或读取,所以在 C 语言程序代码的编写过程中,在对文件进行操作时,需要刷新缓冲区并在文件操作结束时关闭文件,否则就可能导致文件的读写操作出现问题

7.总结:

今天我们了解了文件操作与管理的相关知识,学习了文件的顺序读写、随机读写、文件读取结束的判定以及文件缓冲区的相关介绍,并且对文本文件和二进制文件有了一定的了解和区分,通过文件操作,可以实现对本地文件的修改与维护,希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

相关文章:

【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C语言进阶 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录1.文件操作1.1 概述…...

图形编辑器:拖拽阻塞优化

大家好&#xff0c;我是前端西瓜哥。在图形编辑器中&#xff0c;想象这么一个场景&#xff0c;我们撤销了一些重要的操作&#xff0c;然后想选中一个图形&#xff0c;看看它的属性。你点了上去&#xff0c;然后你发现你再也无法重做了。 你以为你点了一下&#xff0c;但其实你…...

c++ 的 Eigen库写 AX=XB的矩阵求解代码

1.AXXB的矩阵求解代码(3*3) #include <iostream> #include <Eigen/Dense>int main() {// 定义矩阵A和BEigen::MatrixXd A(3, 3);A << 1, 2, 3,4, 5, 6,7, 8, 9;Eigen::MatrixXd B(3, 3);B << 10, 11, 12,13, 14, 15,16, 17, 18;// 求解AXXBEigen::Mat…...

正点原子linux驱动篇

linux驱动开发与裸机开发的区别 裸机直接操作寄存器&#xff0c;有些mcu提供了库&#xff0c;但还是很底层 1、linux驱动开发直接操作寄存器很麻烦不现实&#xff0c;主要是根据linux驱动框架进行开发&#xff08;就是有很多操作都是一样的&#xff0c;我们只需要对一个程序模…...

MATLAB绘制雷达图/蜘蛛图

雷达图/蜘蛛图 1 方法一 函数来源为MATLAB | 如何使用MATLAB绘制雷达图(蜘蛛图) 1.1 调用函数 1.2 案例 2 方法二 函数来源为MATLAB帮助-spider_plot 2.1 调用函数 语法&#xff08;Syntax&#xff09;&#xff1a; spider_plot(P)spider_plot(P, Name, Value, ...)h …...

算法入门,十字路口选择的案例,如果是南方,则向前行

从if判断start; 十字路口的案例 class HelloWorld { static void Main(string[] args) { /* Write C# code in this online editor and run it. */ Console.WriteLine("Hello World!"); string f…...

父传子与子传父步骤

父传子&#xff1a; 问题&#xff1a;父页面中引入子组件 把想要传给子页面的值用在子组件中用 &#xff1a;值“值” (用同一个值好区分)来绑定。 在子页面中用props接收 子组件不能改变父组件传过来的值。&#xff08;传多个页面的时候是&#xff0c;比如父传孙的时候我会…...

Java concurrency - Task Execution

1.在单个线程里处理所有的请求&#xff1a;接受请求-处理请求 优点&#xff1a;逻辑简单 缺点&#xff1a;吞吐量低&#xff0c;资源利用率低&#xff0c;响应时间长 2.每个任务分配一个单独的线程来处理&#xff1a; 接受请求-创建线程-在线程里处理请求 优点&#xff1a; …...

浅谈BOM

什么是BOM BOM对于每个前端都不陌生&#xff0c;但是很多人都停留在表面&#xff0c;而没有深层次的研究过它。JavaScript有一个非常重要的运行环境就是浏览器&#xff0c;而且浏览器本身又作为一个应用程序需要对其本身进行操作&#xff0c;所以通常浏览器会有对应的对象模型…...

每日学术速递2.24

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.LG 1.BUAA_BIGSCity: Spatial-Temporal Graph Neural Network for Wind Power Forecasting in Baidu KDD CUP 2022 标题&#xff1a;BUAA_BIGSCity&#xff1a;百度KDD CUP 2022风电预测…...

SpringBoot 面试问答总结(VIP典藏版)

1. 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 开源组织下的子项目&#xff0c;是 Spring 组件一站式解决方案&#xff0c;主要是简化了使用Spring 的难度&#xff0c; 简省了繁重的配置&#xff0c;提供了各种启动器&#xff0c;使开发者能快速上手。 2. 为什…...

CSS 定位网页元素【快速掌握知识点】

目录 前言 一、position: static 二、position: relative 三、position: absolute 四、position: fixed 五、position: sticky 前言 当我们在设计网页时&#xff0c;经常需要对网页中的元素进行定位&#xff0c;以便它们出现在我们想要的位置。在 CSS 中&#xff0c;我们…...

构建Docker基础镜像(ubuntu20.04+python3.7.1+chrome101+chromedriver101)

文章目录 一、前置条件1.下载 chrome【google-chrome-stable_current_amd64.deb】2.下载 chromedriver【chromedriver_linux64.zip】3.创建 ubuntu 镜像源文件【sources.list】二、构建方法1.构建目录1.创建DockerFile2.打包镜像一、前置条件 要先下载一个支持 linux 的 浏览器…...

最新最全Java面试知识

工作也有好些年了&#xff0c;从刚毕业到前几年看过无数的面试题&#xff0c;在这个过程中也作为面试官面试过其他人&#xff0c;总想着自己写一个面试总结&#xff0c;随着自我认识的变化&#xff0c;一些知识点的理解也越来越不一样了。写下来温故而知新。很多问题可能别人也…...

个人电脑需求严重疲软,联想集团财务前景仍不乐观

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 财务业绩 联想集团&#xff08;00992&#xff09;于2月16日盘后公布了2023财年第三季度财报。 财报显示联想集团2023年第三季度的收入为152.67亿美元&#xff0c;从2022年第三季度的2011.27亿美元下降了24.1%。这也导致该公…...

软件测试面试在简历上写了“精通”后,拥有工作经验的我被面试官问到窒息...

前言 如果有真才实学&#xff0c;写个精通可以让面试官眼前一亮&#xff01; 如果是瞎写&#xff1f;基本就要被狠狠地虐一把里&#xff01; 最近在面试&#xff0c;我现在十分后悔在简历上写了“精通”二字… 先给大家看看我简历上的技能列表&#xff1a; 熟悉软件测试理…...

色环电容读数方法要点总结

🏡《总目录》 目录 1,概述2,读数方法3,颜色对照表3.1,颜色与电容值数字对照关系表3.2,颜色与10的指数数字对照关系表3.3,颜色与误差对照关系表4,总结1,概述 本文简单介绍色环电容的读数方法。 2,读数方法 如下图所示色环电容共有四个色环。最粗的被命名为第1环,依次…...

C++函数新思想和标准的输入和输出

欢迎来观看温柔了岁月.c的博客目前设有C学习专栏C语言项目专栏数据结构与算法专栏目前主要更新C学习专栏&#xff0c;C语言项目专栏不定时更新待C专栏完毕&#xff0c;会陆续更新C项目专栏和数据结构与算法专栏一周主要三更&#xff0c;星期三&#xff0c;星期五&#xff0c;星…...

华为OD机试真题Java实现【汽水瓶】真题+解题思路+代码(20222023)

汽水瓶 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是 5 瓶,方法如下:先用 9 个空瓶子换3瓶汽水,喝掉 3 瓶满的,喝完以后 4 个空瓶子,用 3 个再换一瓶,喝掉这瓶满的,这时候剩 2 个空瓶子。…...

WindownsPowershell中的单引号和双引号

WindownsPowershell中的单引号和双引号 目录标题WindownsPowershell中的单引号和双引号单引号对中,可以直接写双引号双引号对中,可以直接写单引号反引号 可以在 双引号对中表示转义双引号对中, 可以用 反引号双引号 表示一个双引号双引号对中, 可以用 反引号单引号 表示一个单引…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...