【C语言】文件操作(1)(文件打开关闭和顺序读写函数的万字笔记)

在这里插入图片描述

文章目录

  • 一、什么是文件
    • 1.程序文件
    • 2.数据文件
  • 二、数据文件
    • 1.文件名
    • 2.数据文件的分类
      • 文本文件
      • 二进制文件
  • 三、文件的打开和关闭
    • 1.流和标准流
      • 标准流
    • 2.文件指针
    • 3.文件的打开和关闭
      • 文件的打开
      • 文件的关闭
  • 四、文件的顺序读写
    • 1.fgetc函数
    • 2.fputc函数
    • 3.fgets函数
    • 4.fputs函数
    • 5.fscanf函数
    • 6.fprintf函数
    • 7.fwrite函数
    • 8.fread函数

一、什么是文件

   我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存,我们可以使⽤⽂件
   文件是计算机系统中的一个基本概念,它是存储在计算机上的信息集合,可以是文本文档、图片、程序等,但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类的)

1.程序文件

   程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)

2.数据文件

   文件的内容不⼀定是程序,而是程序运行时读写的数据,比如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件

二、数据文件

   本文着重讨论的是数据文件,在以前我们学的知识中,所处理的数据的输⼊都是以键盘输⼊数据,用显示器输出
   但是我们之前的程序结果输出到显示器后,结束程序,这个结果不会被保存,那是因为我们运行程序时,把数据放在了内存,程序结束后,内存回收了,数据也就没了
   那我们很多情况下想把数据永久保存起来,就要使用磁盘上的数据文件存储起来,存储到磁盘的数据就会一直保存,当需要使用数据时,就从数据文件中将数据读入到我们的内存进行操作,本文将会讲解的就是操作数据文件

1.文件名

   ⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤,这个文件标识就是我们常说的文件名,⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀

例如: c:\code\test.txt

   在这个例子中,文件的路径就是c:\code\,文件名的主干就是test,文件后缀是.txt,说明这个文件是一个文本文件,属于数据文件之一
   而路径又可以分为相对路径和绝对路径,上面演示的就是绝对路径,如果对这个有兴趣的话,可以自行搜索文章学习,这里我们还是继续进行我们的文件操作的学习

2.数据文件的分类

   根据数据的组织形式,数据⽂件被称为⽂本⽂件或者⼆进制⽂件

文本文件

   如果要求在外存上以ASCII码的形式存储,则需要在存储前转换,以ASCII字符的形式存储的⽂件就是⽂本⽂件
   简单的理解就是,如果打开这个文件你可以看懂上面的信息,那么就是文本文件,例如汉字,英文字母等等信息,文本文件常见的后缀为:.txt 和 .docx 以及 .rtf

二进制文件

   数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的⽂件中,就是⼆进制⽂件,由于里面是0和1序列组成的二进制,然后转换出来的字符,所以根本看不懂里面的内容
   我们可以在VS运行下面的代码,如果不懂也没有关系,后面会讲到,这里只是举一个例子:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
int main()
{
	int a = 10000;
	//以二进制写的方式打开
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror(fopen);
		return 1;
	}
	//⼆进制的形式写到⽂件中
	fwrite(&a, 4, 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

   我们运行它之后会发现当前代码路径下会多出一个test.txt的文件,打开当前代码路径的方法是单击左上角文件夹图标,如图:
在这里插入图片描述
   然后我们双击打开这个文件:
在这里插入图片描述
   可以看到我们明明是将10000写入到了这个文件中,但是最后我们打开文件后发现是一个我们看不懂的字符,原因就是我们写入时,是以二进制的写入方式打开文件的,里面存储的是二进制的信息

三、文件的打开和关闭

1.流和标准流

   我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河
   比如向文件里输入信息和向屏幕输入信息的方式不同,但是程序员不必了解它们如何输入的,程序员只需要去往对应的流写入或读出操作,不需要担心各种设备的输入输出操作
   ⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作,打开流的方法我们后面会讲到

标准流

   刚刚提到了,如果要输入或者读取信息,都要打开流,然后进行操作,那么每次我们在键盘输入信息,在屏幕上打印信息为什么没有专门打开流呢?那是因为C语言程序在启动时,默认打开了3个标准流:

  • stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据
  • stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出流中
  • stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯

   这是默认打开的三个标准流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的,它们的类型是FILE*的指针,通常称为文件指针,对文件的操作就是使用文件指针进行操作

2.文件指针

   缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”,每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)
   这些信息是保存在⼀个结构体变量中的,该结构体类型是由系统声明的,这个结构体就叫FILE,我们可以在VS2013编译环境提供的 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结构的变量,并填充其中的信
息,使⽤者不必关⼼细节
   C语言⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便,下面我们可以创建一个文件指针变量:

FILE* pf;//⽂件指针变量

   这里定义的pf是⼀个指向FILE类型数据的指针变量,可以使pf指向某个⽂件的⽂件信息区(⼀个结构体),通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件,如图:
在这里插入图片描述

3.文件的打开和关闭

   ⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件,现在我们就来学习如何打开和关闭文件
   ANSI C 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件,在打开⽂件的同时,它们都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系

文件的打开

   我们来看看打开文件的函数fclose的原型:

FILE * fopen ( const char * filename, const char * mode );

   如果文件打开成功了,那么就会返回一个FILE*的指针,我们可以用一个文件指针变量接收,然后我们后续就可以通过这个文件指针变量对这个文件进行操作
   如果文件打开失败了,那么就会返回一个空指针NULL,所以我们在使用fopen后,最好再判断一下它的返回值是否是空指针,如果是空指针说明文件打开失败,直接返回
   它的参数有两个,第一个是我们要打开的文件的名字,第二个参数是我们打开文件的方式,是以读的方式,还是写的方式,还是读写等等方式,如下图:
在这里插入图片描述
   在上图中展示了文件打开的方式,以及如果文件不存在,会做出什么操作,现在我们还没有讲解怎么对文件进行读写,所以有点懵也没有关系,在后面的读写部分都会讲解,这里只了解一下
   接下来我们来试着写一个代码,以只读的方式打开一个文本文件test.txt,如下:

	FILE* pf = fopen("test.txt", "r");//打开文件
	//判断是否打开成功,打开失败就返回错误信息并返回:
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

   这样我们就打开了文件了,至于读写操作我们后面讲,现在先来看看如何关闭文件

文件的关闭

   我们来看看关闭文件的函数fclose的原型:

int fclose ( FILE * stream );

   它的返回值是int类型,如果文件关闭成功就返回0,如果文件关闭失败就返回EOF
它的参数是我们要关闭的流,在这里我们要关闭文件,就把文件的流,也就是对应的文件指针变量传过来
   我们要注意的是,关闭文件后,pf这个指针变量就指向野指针了,所以最好关闭文件后将其置为空指针NULL,我们来看看关闭文件关闭的过程:

//关闭⽂件
int fclose (pf);
//为了防止pf成为野指针,可以把它置为空指针
pf = NULL;

   这就是我们关闭文件的过程,接下来我们就学习最关键的文件读写操作

四、文件的顺序读写

   文件的顺序读写就是按照文件数据从头到尾进行读写,读写操作也是由我们的函数来完成的,如下表:
在这里插入图片描述
   我们接下来就就一一讲解这些函数:

1.fgetc函数

   我们要学习的第一个函数是fgetc,它的作用就是从流中获取一个字符,不是应该属于输出吗?那么为什么在表中它叫字符输入函数呢?
   这是我们要注意的一点,我们说的输入输出是站在内存的角度思考的,我们从流里面获取了一个字符,对流来说,也就是对文件来说是输出,但是如果站在内存角度思考就会发现,获取的字符存储到内存中了,应该是属于输入,所以我们说的输入输出都是基于内存角度的
   实在不理解也没什么,我们掌握它的用法就行,我们来看看它的原型:

int fgetc ( FILE * stream );

   它的参数就是我们要从哪个流里面获取一个字符,在这里我们要操作文件,很明显就是从文件流里面获取字符,所以需要填一个文件指针变量进去
   它的返回值是整型,如果成功从文件中读取了一个字符,那么就返回这个字符的Ascll码值,如果读取失败或者读取到了文件末尾,那么就返回EOF,现在我们就来使用一下它
   我们首先明确一下条件,在当前代码路径下有一个test.txt的文件,里面的内容是hello world!,然后我们开始写代码,由于这是第一遍,所以我来带大家实现一下全过程,后面文件的打开和关闭就不会再讲解了
   首先我们要以读的形式打开文件,然后用文件指针变量接收,判断返回值是否为空,如下:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	return 0;
}

   随后我们就开始使用fgetc函数来实现读取操作,用一个字符变量ch来接收它的返回值,然后打印ch,如下:

	char ch = fgetc(pf);
	printf("%c\n", ch);

   随后就是最后一步:关闭文件,注意关闭文件后要把pf置为空指针,如下:

fclose(pf);
pf = NULL;

   完整代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = fgetc(pf);
	printf("%c\n", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}

   最后我们来运行一下代码:
在这里插入图片描述
   可以看到我们成功读取了一个字符h,那么问题来了,如果我想将文件中的字符全部读出来怎么办呢?我们也不是每一次都知道文件中有多少个字符
   这个时候我们可以利用fgetc的返回值,创建一个while循环,只要fgetc的返回值不是EOF就一直循环,每次循环把读取到的字符打印出来,直到将所有字符读取完毕返回EOF结束循环,如下:

	char ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c", ch);
	}

   接着我们再次运行程序试试:
在这里插入图片描述
   可以看到这里就把文件中的所有字符都读出来了

2.fputc函数

   fgetc函数和fputc函数很相似,只是fgetc是将一个字符从流中读出,而fputc的作用是将一个字符写入到文件中,我们来看看它的原型:

int fputc ( int character, FILE * stream );

   它的第一个参数就是我们要写入的字符,第二个参数就是我们的流,我们操作文件,所以要写文件流
   如果写入成功,那么它的返回值就是这个字符的Ascll码值,如果失败就返回EOF,当然,它的返回值我们很少用到
   接着我们就使用一下这个函数,这里要强调的一点是,以写的方式打开文件,第一步会清空文件中的内容,然后再进行写的操作,如果不想文件中的内容被清楚,可以使用追加的方式打开
   我们这里就可以使用写的方式打开test.txt文件,让它将里面的hello world!删除了,然后我们再使用fputc来写入一个字符,如下:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = 0;
	fputc('x', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

   运行代码后屏幕上没有出现任何信息,接着我们就来看看test.txt文件有没有按预期被修改,如图:
在这里插入图片描述
   可以看到,hello world!已经被清除了,并且字符x已经被我们写入到文件了

3.fgets函数

   fgets函数的作用是从文件中读出一行的信息,我们来看看它的原型:

char * fgets ( char * str, int num, FILE * stream );

   它的第一个参数就是我们要把读出的一行数据放入哪个字符串,第二个参数就是我们要读出几个字符,最后一个参数就是要从哪个流中读取数据
   如果读取成功,那么它的返回值就是从文件中读取出的第一行的字符串的首地址,可以使用%s的形式打印出来,如果读取失败,则会返回空指针NULL
   接着就让我们使用一下这个函数,首先明确前提,当前目录下有一个test.txt的文件,里面的内容有两行,第一行是hello,第二行是world!,我们来读取它的第一行,然后把它的第一行内容打印出来:

	char arr[20] = { 0 };
	fgets(arr, 20, pf);
	printf("%s\n", arr);

   完整代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20] = { 0 };
	fgets(arr, 20, pf);
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

   我们来看看代码运行截图:
在这里插入图片描述
   还是同样的问题,如果我想将文件的所有行都读出来呢?虽然我们现在知道有两行数据,可以只调用两次fgets函数,但是万一下次遇到很多行数据呢?
   所以这里我们还是要利用它的返回值,创建一个while循环,如果fgets没有返回空指针,说明读取到了一行信息,那么我们就把它打印出来,如果返回空指针就结束循环,如下:

	char arr[20] = { 0 };
	while (fgets(arr, 20, pf))
	{
		printf("%s", arr);
	}

   我们来看看代码运行结果:
在这里插入图片描述
   可以看到代码自动把所有行打印出来了

4.fputs函数

   fgets函数和fputc函数很相似,只是fgets是将一行字符从流中读出,而fputs的作用是将一行字符写入到文件中,我们来看看它的原型:

int fputs ( const char * str, FILE * stream );

   这个函数的第一个参数就是我们要写入的字符串,第二个参数就是要写入的流
如果文件写入成功,那么就返回一个非零的值,如果写入失败就返回EOF
   接着我们就来使用fputs向文件test.txt写入一行字符hello world!,如下:

	char arr[20] = "hello world!";
	fputs(arr, pf);

   完整代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20] = "hello world!";
	fputs(arr, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

   然后我们运行代码后来看看test.txt有没有被写入这一行信息:
在这里插入图片描述
   可以看到文件里已经成功写入了一行信息

5.fscanf函数

   fscanf是以格式化的方式对文件进行读取操作,它与scanf函数的使用方法相似,它们的区别就是fscanf的第一个参数是流,后面和scanf的参数一样,我们来对比一下scanf和fscanf的原型:

//scanf的原型:
int scanf ( const char * format, ... );
//fscanf的原型:
int fscanf ( FILE * stream, const char * format, ... );

   可以看到它们的区别就是fscanf多一个流的选择,它们的返回值也是一样的,都是返回成功读取的项目的个数,如果读取失败返回EOF,如果还不熟悉scanf可以参考文章:
【C语言】printf和scanf函数详解
   我们这里也可以顺便说一下它们之间的关系,scanf是从标准输入流读取数据,而fscanf可以从任何流中读取数据,那么fscanf也必然可以从标准输入流读取数据,此时它们的作用就是一致,我们在上面也说过标准输入流是stdin,我们将fscanf的第一个参数写成标准输入流stdin就可以了,如下:

fscanf (stdin , const char * format, ... );
//等价于scanf

   说明了它们的关系,我们就来示例使用一下fscanf,我们的前提条件是:当前文件夹下有一个test.txt文件,里面包含的数据有:123 hello,现在我们要以格式话的方式将它们读取出来,也就是将123读取为整型,hello读取为字符串
   首先我们要创建一个整型变量和一个字符数组,用来存储我们读取到的信息,然后将它们打印出来,代码如下:

	int i = 0;
	char arr[20] = { 0 };
	fscanf(pf, "%d %s", &i, arr);
	printf("%d %s", i, arr);

   可以看到fscanf和scanf确实只有第一个参数的不同,接着我们来看看完整的代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int i = 0;
	char arr[20] = { 0 };
	fscanf(pf, "%d %s", &i, arr);
	printf("%d %s", i, arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

   我们来看看代码运行结果:
在这里插入图片描述

6.fprintf函数

   fprintf函数和printf函数又非常相似,也是第一个参数不同,其它的使用方法一致,fprintf的原型如下:

int fprintf ( FILE * stream, const char * format, ... );

   它的返回值就不说了,与printf一致,不知道的可以看上面的链接,有printf的详细使用教程,它的参数也只是比printf多一个
   它们只是作用不同,fprintff的作用是向所有流中写入数据,而printf是向标准输出流写入数据,fprintf要全面一些,当fprintf的第一个参数是标准输出流stdout的时候,它的作用就和printf相同了,如下:

fprintf(stdout, const char * format, ... )
//等价于printf

   说完它们的关系我们就回到正题,来使用一下fprintf函数对文件test.txt写入一些格式化的数据,比如写入字符串world和浮点型的3.14,如下:

float f = 3.14f;
char arr[20] = "world";
fprintf(pf, "%s %f", arr, f);

   完整代码如下:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	float f = 3.14f;
	char arr[20] = "world";
	fprintf(pf, "%s %f", arr, f);
	fclose(pf);
	pf = NULL;
	return 0;
}

   接着我们运行代码来看看文件test.txt有没有被修改,如下:
在这里插入图片描述
   可以看到文件被成功写入了格式化的数据

7.fwrite函数

   我们要讲的最后两个函数fread和fwrite与上面讲的函数不同,上面的函数都是对文件写入或读取我们看得懂的文本信息,而这两个函数是对文件写入或读取二进制信息
   也就是对二进制文件进行操作,所以打开文件时要使用rb或者wb的方式,我们首先来看看fwrite函数,它是向文件写入二进制的信息,它的原型如下:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

   它的第一个参数是我们要写入的信息的首地址,第二个参数size就是我们要写入的信息的一个元素的大小,第三个参数count是我们要写入的元素的个数,最后一个参数就是我们要往哪个流写入信息
   它的返回值就是被成功写入文件的元素个数
   接着我们就赶紧去使用一下fwrite为test.txt文件写入一些二进制信息,我们要写的就是整型1到5,我们可以使用数组的方式,如下:

int arr[] = { 1,2,3,4,5 };
fwrite(arr, sizeof(arr[0]), 5, pf);

   然后我们来看看完整代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "wb");//二进制写的方式打开
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[] = { 1,2,3,4,5 };
	fwrite(arr, sizeof(arr[0]), 5, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

   然后我们来运行一下代码,看看test.txt文件有没有发生改变:
在这里插入图片描述
   可以看到test.txt文件被写入了一些二进制信息,但是我们看不出来是什么,也就不知道里面是不是装的我们写入的整型1到5,所以我们接下来学习对二进制文件信息进行读取的函数fread

8.fread函数

   fread函数的作用就是从文件中读取二进制的信息,刚好和fwrite搭配使用,我们来看看它的原型:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

   可以看到它的参数和返回值都和fwrite差不多,没错,它们的原型的含义基本一致,这里就不多讲了
   在刚刚使用了fwrite向文件写入了整型1到5后,我们看不出来文件中的内容是否正确,现在我们就使用fread将里面的信息读取出来,看看是否是整型1到5,如下:

	int arr[5] = { 0 };
	fread(arr, sizeof(int), 5, pf);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}

   完整代码:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[5] = { 0 };
	fread(arr, sizeof(int), 5, pf);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

   我们来运行代码看看fread帮我们从test.txt读出的信息是否是整型1到5:
在这里插入图片描述
   可以看到成功打印出来了整型1到5,从这里也验证了之前我们的fwrite使用正确了

   今天的分享就到这里结束啦,虽然只是文件操作的一部分,但是还是有一万字,基本上讲完了我们在读写时使用的函数,但是还是没有把文件操作部分要掌握的内容完全讲完
   所以文件操作还有下一篇文章,uu们敬请期待~
   那么今天说到这里,bye~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI开发-三方库-Hugging Face-Pipelines

1 需求 需求1&#xff1a;pipeline支持的任务类型 需求2&#xff1a;推理加速使用CPU还是GPU 需求3&#xff1a;基于pipeline的文本分类示例 需求4&#xff1a;pipeline实现原理 模型使用步骤&#xff08;Raw text -》Input IDs -》Logits -》Predictions&#xff09;&…

k8s 1.28.2 集群部署 harbor v2.11.1 接入 MinIO 对象存储

文章目录 [toc]提前准备什么是 HarborHarbor 架构描述Harbor 安装的先决条件硬件资源软件依赖端口依赖 Harbor 在 k8s 的高可用Harbor 部署Helm 编排YAML 编排创建 namespace导入镜像部署 Redis部署 PostgreSQL部署 Harbor core部署 Harbor trivy部署 Harbor jobservice部署 Ha…

前端考试总结

1HTML标签 h标题标签 块级标签 独占一行 p段落标签 同上 br换行标签 单标签 img图片标签 内联标签:不独占一行(src图片地址 alt图片的替代文字 title鼠标悬停提示文字) a超链接标签 同上 (href跳转路径 target属性{_blank新窗口打开 _self在当前窗口打开}) 列表标签(ul无…

VSCODE 导入cubeide工程

1.下载vscode及插件STM32 VS Code Ectersion 版本号1.0.0&#xff0c;之后这个有导入功能。 2.等待自动安装对应插件&#xff0c;提示缺少什么就补什么 3.在左侧出现stm32图标。点击Import a local project导入本地项目。 4.报错 [{"resource": "/f:V11/cmak…

前端html,css 样式巩固1

想做这样 一个效果 点击图片切换 当前的选中图片 我们使用 原生的js html 来开发这个 直接粘贴代码 相信大家 都能看懂的 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" …

抖音视频制作怎么暂停画面,抖音视频怎么让它有暂停的效果

千万别滥用视频特效&#xff0c;不然它能毁掉你的抖音作品。在创作过程中&#xff0c;应尽量使用类似暂停画面、隐形字幕这样的视觉特效&#xff0c;可以显著提高作品的视觉体验。增强视频表现力的同时&#xff0c;也不会让画面看起来过于夸张。有关抖音视频制作怎么暂停画面的…

Springboot 整合 Java DL4J 实现文物保护系统

&#x1f9d1; 博主简介&#xff1a;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编程&#xff0c;…

2011年国赛高教杯数学建模A题城市表层土壤重金属污染分析解题全过程文档及程序

2011年国赛高教杯数学建模 A题 城市表层土壤重金属污染分析 随着城市经济的快速发展和城市人口的不断增加&#xff0c;人类活动对城市环境质量的影响日显突出。对城市土壤地质环境异常的查证&#xff0c;以及如何应用查证获得的海量数据资料开展城市环境质量评价&#xff0c;研…

应用层协议 序列化

自定义应用层协议 例子&#xff1a;网络版本计算器 序列化反序列化 序列化&#xff1a;将消息&#xff0c;昵称&#xff0c;日期整合成消息-昵称-日期 反序列化&#xff1a;消息-昵称-日期->消息&#xff0c;昵称&#xff0c;日期 在序列化中&#xff0c;定义一个结构体…

【Pycharm默认解释器配置文件】怎样删除配置解释器的无效历史记录?

有时候我们希望删除无效的解释器路径&#xff0c;可以找到这个文件&#xff0c;进行删除修改。 C:\Users\你的用户名\AppData\Roaming\JetBrains\PyCharm2022.3\options\jdk.table.xml直接删除解释器名称对应的一整个<jdk version"2">节点即可&#xff01; …

2023年ICPC亚洲合肥赛区赛 C. Cyclic Substrings

题目 题解 #include<bits/stdc.h> using namespace std; // #define int long long #define ll long long const int maxn 6e6 5; const int mod 998244353; int fail[maxn];//fail[i]表示i结点代表的回文串的最大回文后缀的编号 int len[maxn]; //len[i]表示结点i代…

大模型涌现判定

什么是大模型&#xff1f; 大模型&#xff1a;是“规模足够大&#xff0c;训练足够充分&#xff0c;出现了涌现”的深度学习系统&#xff1b; 大模型技术的革命性&#xff1a;延申了人的器官的功能&#xff0c;带来了生产效率量级提升&#xff0c;展现了AGI的可行路径&#x…

UDP/TCP协议

网络层只负责将数据包送达至目标主机&#xff0c;并不负责将数据包上交给上层的哪一个应用程序&#xff0c;这是传输层需要干的事&#xff0c;传输层通过端口来区分不同的应用程序。传输层协议主要分为UDP&#xff08;用户数据报协议&#xff09;和TCP&#xff08;传输控制协议…

mongodb-7.0.14分片副本集超详细部署

mongodb介绍&#xff1a; 是最常用的nosql数据库&#xff0c;在数据库排名中已经上升到了前六。这篇文章介绍如何搭建高可用的mongodb&#xff08;分片副本&#xff09;集群。 环境准备 系统系统 BC 21.10 三台服务器&#xff1a;192.168.123.247/248/249 安装包&#xff1a…

Javaweb基础-vue

Vue.js Vue是一套用于构建用户界面的渐进式框架。 起步 引入vue <head><script src"static/js/vue2.6.12.min.js"></script> </head> 创建vue应用 <body> <div id"index"><p>{{message}}</p> </div>…

Java的walkFileTree方法用法【FileVisitor接口】

在Java旧版本中遍历文件系统只能通过File类通过递归来实现&#xff0c;但是这种方法不仅消耗资源大而且效率低。 NIO.2的Files工具类提供了两个静态工具方法walk()和walkFileTree()可用来高效并优雅地遍历文件系统。walkFileTree()功能更强&#xff0c;可自定义实现更多功能&am…

5.3章节python中字典:字典创建、元素访问、相关操作

1.字典的创建和删除 2.字典的访问和遍历 3.字典的相关操作 4.字典的生成式 一、字典的创建和删除 字典&#xff08;dictionary&#xff09;是一种用于存储键值对&#xff08;key-value pairs&#xff09;的数据结构。每个键&#xff08;key&#xff09;都映射到一个值&#xf…

基于FPGA的信号发生器verilog实现,可以输出方波,脉冲波,m序列以及正弦波,可调整输出信号频率

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 输出方波 输出脉冲波 输出m随机序列 输出正弦波 2.算法运行软件版本 vivado2019.2 3.部分核心程序 &#xff08;完整…

顺序表算法题【不一样的解法!】

本章概述 算法题1算法题2算法题3彩蛋时刻&#xff01;&#xff01;&#xff01; 算法题1 力扣&#xff1a;移除元素 我们先来看这个题目的要求描述&#xff1a; 把与val相同数值的元素移除掉&#xff0c;忽略元素的相对位置变化&#xff0c;然后返回剩下与val值不同的元素个数…

OpenCV高级图形用户界面(10)创建一个新的窗口函数namedWindow()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 创建一个窗口。 函数 namedWindow 创建一个可以作为图像和跟踪条占位符的窗口。创建的窗口通过它们的名字来引用。 如果已经存在同名的窗口&am…