文件操作 -- C语言

news2024/9/19 6:41:43

 在之前学习的时候,我们可以发现当程序运行完,我们之前保存的数据就会消失,再次运行时还得重新输入,为了使我们保存的数据在下次运行时还能使用,我们这篇文章来学习一下怎么使用文件操作,将我们的数据保存在文件中。

目录

1.什么是文件

2.文件名

3.文件指针

4.文件的打开与关闭

5.文件的顺序读写

6.文件的随机读写

7.文件类型 

8.文件结束的判断

9.文件缓冲区


1.什么是文件

磁盘(硬盘)上的文件是文件

但是在程序设计中,我们一般谈的文件有两种:程序文件数据文件

程序文件

包括源程序文件(后缀为.c),源程序编译后生成的目标文件(Windows环境后缀为.obj),可执行程序(Windows环境后缀为.exe)。

 数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。例如创建的.txt文件。

本篇文章讨论的是对数据文件的相关操作。

在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到终端的屏幕上。


其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。
 

2.文件名

一个文件要有一个唯一的文件标示,以便用户识别和引用

文件名包含3部分:文件路径 + 文件名主干 + 文件后缀

例如:c:\code\test.txt

为了方便起见,文件标识常被称为文件名

3.文件指针

在学习文件操作时,关键的概念是”文件类型指针“,简称”文件指针“

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE。

例如,VS2008编译环境提供的 stdio.h 头文件中有以下的文件类型申明:

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

这里只需要知道FILE是一个结构体,存放文件的相关信息就行了。

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构体的变量,并填充其中的信息,使用者不必关心细节。

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

下面我们可以创建一个FILE*的指针变量

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

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件

图解:

4.文件的打开与关闭

文件在读写之前,应该先打开文件,在使用结束之后应该关闭文件

在编程程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

ANSIC 规定使用 fopen 函数来打开文件,fclose 来关闭文件。

FILE* fopen(const char* filename, const char* mode);
返回文件信息区的地址       文件名          打开方式
int fclose (FILE* stream);
              要关闭的文件流  也就是文件信息区的地址

打开方式如下

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

注意:当以写(含"w")的形式打开文件时,原文件的内容都会被销毁掉。 

 示例代码:

#include<stdio.h>

int main()
{
	//fopen返回文件信息区的地址,通过文件信息区操作文件
	//打开文件
	//打开成功,放回一个指向FILE类型的指针
	//打开失败,返回空指针
	FILE* pf = fopen("test.txt", "r");//这里文件是相对路径,也可以用绝对路径
	if (pf == NULL)
	{
		//打开失败
		perror("fopen:");//打印错误信息
		return 1;
	}

	//写文件
    //....

	//关闭文件
	fclose(pf);
	pf = NULL;//置空

	return 0;
}

5.文件的顺序读写

顺序读写,说的是当我们在读或写文件的时候,文件指针会自动向后移动,因此我们可以使用循环将整个文件读/写完。

函数:

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

输入输出 / 读和写 都是相对内存而言的 

示例:

fgetc fputc :

int fgetc ( FILE * stream );

int fputc ( int character, FILE * stream );

 一次读/写一个字符的空间,成功返回字符的ASCII码值,失败返回EOF

//写文件
#include<stdio.h>

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

	//写文件
	//把26个字母写到文件中
	for(int i=0;i<26;i++)
	{
		fputc('a'+i, pf);//写一个字符
	}

	fclose(pf);
	pf = NULL;

	return 0;
}
//读文件
#include<stdio.h>

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

	//读文件

	//读一个字符,返回躲到字符的ASCII码值
	//读取失败,或者读到文件末尾 返回EOF -1
	for(int i=0;i<26;i++)
	{
		int ch = fgetc(pf);
		//读取完一个会让文件内容指针向后移动,可以读取全部数据,不会只读a
		//与pf++不同,pf指向的是整个文件信息区
		printf("%c", ch);
	}

	fclose(pf);
	pf = NULL;

	return 0;
}

fgets 与 fputs :  

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

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

 一次读/写一行的空间,成功返回保存一行字符的数组地址,失败返回NULL

//fputs 写一行数据
#include<stdio.h>

int main()
{
	//打开文件
	FILE*pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写一行数据  hello world
	fputs("hello world\n",pf);
	fputs("xilanhua\n", pf);//会追加
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

//fgets 读一行数据
#include<stdio.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");//默认在程序所在工程目录下生成
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读一行数据 
	//char* fgets(char* str,int num, FILE* stream);
	//将读到的字符串拷贝放到 str字符数组中,
	//然后最多读num-1 个,因为第num个放 '\0'
	char arr[20];
	fgets(arr, 5, pf);//读一行,读到 '\n' 为止
	printf("%s\n", arr);//hell
	
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

格式化的读写

fprintf 与 fscanf :

int fprintf ( FILE * stream, const char * format, ... );
                                               ...可变参数列表
int fscanf ( FILE * stream, const char * format, ... );

可以发现,fprintf 和 fscanf 与 printf 和 scanf 的参数列表部分只是多了 FILE* stream

示例:

//fprintf 写文件
#include<stdio.h>

struct S
{
	int n;
	float f;
	char arr[20];
};
int main()
{
	struct S s = { 100,3.14f,"zhangsan" };

	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fprintf(pf, "%d %f %s", s.n, s.f, s.arr);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}


//读文件
struct S
{
	int n;
	float f;
	char arr[20];
};

int main()
{
	struct S s;

	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	fscanf(pf, "%d %f %s", &(s.n), &(s.f), &(s.arr));

	printf("%d %f %s", s.n, s.f, s.arr);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

sprintf 与sscanf : 

 与 fprintf 和 fscanf 相似的还有 sprintf 和 sscanf ,前者是数据与文件之间的操作,后者是数据与字符串之间的操作。

int sprintf ( char * str, const char * format, ... );

int sscanf ( const char * s, const char * format, ...);
  • sscanf : 把一个格式化的数据 写到 字符串中
  • sprintf : 把 字符串中 的 格式化数据 读出来

示例:

#include<stdio.h>
struct S
{
	int n;
	float f;
	char arr[20];
};
int main()
{
	struct S s = { 200,3.5f,"wangwu" };
	//把一个结构体转换为字符串
	char arr[50] = { 0 };
	sprintf(arr, "%d %f %s\n", s.n, s.f, s.arr);
	printf("字符串的数据:%s\n", arr);//以字符串的形式打印
	
	//把一个字符串 转换为 对应的格式化数据
	struct S tmp = { 0 };

	sscanf(arr, "%d %f %s", &tmp.n, &tmp.f, &tmp.arr);
	printf("格式化的数据:%d %f %s\n", tmp.n, tmp.f, tmp.arr);
	return 0;
}

上面的函数适用于所有输入/输出流,那么流是什么意思:

流可以理解为水流,数据的传输像水一样流动,可以在里面 放/拿 数据。

文件,屏幕,网络,等外部设备,流知道怎么与外界设备交互,我们只需要对流进行操作就可以。

 读写文件的时候:文件流

一个C语言程序会默认打开这3个流

  1. 终端设备   屏幕  标准输出流 stdout
  2. 键盘                   标准输入流 stdin
  3. 屏幕                    标准错误流 stderr

stdout stdin stderr 都是FILE* 的指针

所以我们不用打开键盘和关闭键盘,而文件需要打开和关闭。

 使用 fputc 从标准输入流中读取数据

//标准输入流
#include<stdio.h>

int main()
{
	//从标准输入流读
	int ch = fgetc(stdin);
	printf("%c", ch);

	return 0;
}

//标准输出流
#include<stdio.h>

int main()
{
	fputc('a', stdout);//标准输出流,打印到屏幕上
	return 0;
}

 二级制读写文件:

fwrite 与 fread :

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

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

示例:

//写文件
#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三",20,95.5f };
	FILE* pf = fopen("test.dat", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&s, sizeof(struct S), 1, pf);
	//字符串的二级制形式与文本的形式是相同的
	//整数和浮点型数据的二级制与文本形式是不同的

	//之前的函数使用字符的形式保存的,是认识的
	//现在是不认识的

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

//读文件
#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };
	FILE* pf = fopen("test.dat", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fread(&s, sizeof(struct S), 1, pf);//返回值是实际成功读到的元素得个数
	
	printf("%s %d %f", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

6.文件的随机读写

我们可以通过 改变文件指针的指向和偏移量 来实现文件的随机读取。主要使用一下三个函数:

fseek:

  • 根据文件的位置和偏移量来定义文件指针
int fseek ( FILE * stream, long int offset, int origin );

ftell:

  • 返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );

rewind:

  • 让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );

示例:

#include<stdio.h>

int main()
{
	//文件中已保存内容为abcdefg
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = 0;
	ch = fgetc(pf);//读取完,文件指针向后移
	printf("%c\n", ch);//a
	ch = fgetc(pf);
	printf("%c\n", ch);//b
	ch = fgetc(pf);
	printf("%c\n", ch);//c
	ch = fgetc(pf);
	printf("%c\n", ch);//d

	printf("%d\n", ftell(pf));//返回文件指针想对于文件起始位置的偏移量

	//我们使用fseek函数打印b
	fseek(pf, -3, SEEK_CUR);//文件指针当前位置
	ch = fgetc(pf);
	printf("%c\n", ch); //b
	
	fseek(pf, 1, SEEK_SET);//文件指针起始位置 
	ch = fgetc(pf);
	printf("%c\n", ch); //b

	fseek(pf, -6, SEEK_END);//文件指针末尾位置 
	ch = fgetc(pf);
	printf("%c\n", ch); //b

	rewind(pf);//让文件指针返回到起始位置
	printf("%d\n", ftell(pf));//0
	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

7.文件类型 

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

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。一个数据在内存中是怎么存储的呢?

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占(int 类型)4个字节(VS2022测试)。

存储方式

1.二级制形式存储

代码示例: 

#include<stdio.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//写文件
	int a = 10000;
	fwrite(&a, sizeof(int), 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

我们打开文件发现是下面的内容:

 不是二级制的形式 ,这是因为我们是以文本的方式打开文件的,我们可以通过添加现有项test.txt,来改变他的打开方式:

我们就可以看到 

 这里是小端存储,所以可以看到这样的效果。

2.用 fprintf 存储数据 (ASCII码值形式)

#include<stdio.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//写文件
	int a = 10000;
	fprintf(pf,"%d",a);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

结果 

 这里存放的就是‘1’   ‘0’  ‘0’  ‘0’  ‘0’  字符对应的ASCII码值(16进制)。

 所以我们以文本形式打开的时候可以看到10000。

8.文件结束的判断

被错误使用的 feof
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)

例如:

  • getc判断是否为EOF.
  • fgets判断返回值是否为NULL.

2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:

  • fread 判断返回值是否小于实际要读的个数。

这些判断的条件都是与这些函数的返回值相关的。 

读取函数另外一个功能:

当读取函数读取失败,返回, 同时设置一个错误状态,使用ferror来检测这个状态,

遇到文件末尾 ,返回,同时设置一个状态,使用feof来检测这个状态 

feof 与 ferror

  • feof 如果是遇到 end of file 文件结束标志而结束的读取操作,返回非0值
  • ferror 如果是遇到 读出失败(错误)而结束的读取操作,返回非0值

示例:

#include<stdio.h>

int main()
{
	//文件内部abcdef
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ",ch);
	}

	if (feof(pf))//检查是否有这样的状态设置,有返回非0
	{
		printf("遇到文件结束标志而结束\n");
	}
	else if(ferror(pf))
	{
		printf("遇到文件错误为结束");
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

9.文件缓冲区

ANSIC标准采用"缓冲文件系统"处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块"文件缓冲区"。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。这让做是为了让操作系统有更多的时间去处理其他内容

 这样还是比较抽象,因为我们看不到缓冲区的存在。

我们可以通过下面一段代码来感受缓冲区的存在:

#include<stdio.h>
#include<windows.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	fputs("abcdef", pf);//先将数据放在缓冲区
	printf("睡眠10秒-已经写了数据,打开test.txt文件,发现文件没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf);//刷新缓冲区,才将输入缓冲区的数据写到文件(磁盘)

	printf("在睡眠10秒—此时,再打开test.txt文件,文件有内容了");
	Sleep(10000);
	fclose(pf);//fcolse 在关闭文件的时候,也会刷新缓冲区
	pf = NULL;
	return 0;
}

fflush 会主动刷新缓冲区,让缓冲区的数据写到磁盘上,刷新后可以发现数据在文件中,之前10秒是文件是没有的。

之前我们运行完程序会发现数据已经到文件中,是因为 fclose 也会刷新缓冲区。 

本篇结束

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

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

相关文章

SQL14 操作符混合运用

select device_id,gender,age,university,gpa from user_profile where university山东大学 and gpa>3.5 or university复旦大学 and gpa>3.8;

Linux 抓包工具——tcpdump

1 简介 用简单的话来定义tcpdump&#xff0c;就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口…

由浅入深探究mysql索引结构原理、性能分析与优化

目录 第一部分&#xff1a;基础知识 第二部分&#xff1a;MYISAM和INNODB索引结构 1、 简单介绍B-tree B tree树 2、 MyisAM索引结构 3、 Annode索引结构 4、 MyisAM索引与InnoDB索引相比较 第三部分&#xff1a;MYSQL优化 1、表数据类型选择 2、sql语句优化 3、系统配置与维护…

Java对称与非对称加密解密(AES与RSA)

尽可能预想所有残酷的可能性、因为现实永远让你无法预警,而且又吝于给人慈悲。——富坚义博 今天我们讨论一下秘钥这个东西 一、对称加密技术与非对称加密技术简述 加密技术可以分为对称与非对称两种。 对称加密、解密即加密与解密用的是同一把秘钥,常用的对称加密技术有DES,A…

MySQL - 连表查询 Join On 详解

1. 连表查询详解 市面上有 7 种连表查询, 总共归为三大类 : 左查询 LEFT JOIN -- 以左表为基准右查询 RIGHT JOIN -- 以右表为基准交叉查询 INNER JOIN -- 查询两表都有的数据 操作描述inner join如果表中至少有一个匹配, 就返回行left join会从左表中返回所有的值…

IDEA 设置文件头的注释信息author,date,description

打开setting设置窗口 file and code Templates 2、编辑Class模版 /*** Author:${USER}* Date:${YEAR}-${MONTH}-${DAY}* Description:TODO* */ 创建一个新JAVA类&#xff0c;测试一下&#xff0c;OK

chatgpt赋能python:如何通过Python赚取外快:SEO技巧分享

如何通过Python赚取外快&#xff1a;SEO技巧分享 作为一名有10年Python编程经验的工程师&#xff0c;我发现Python不仅用来写代码&#xff0c;还可以用来赚取外快。SEO是一个非常赚钱的市场&#xff0c;而Python可以帮助我们更好地优化网站&#xff0c;从而实现更高的排名&…

一步一步学OAK之四:实现如何在低延迟下使用高分辨率视频

目录 Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 创建pipelineSetup 5: 创建节点Setup 6: 设置节点的属性和参数。Setup 7: 建立链接关系Setup 8: 连接设备并启动管道Setup 9: 创建与DepthAI设备通信的输入队列和输出队列Setup 10: 主循环获取视频帧显示…

深度学习与神经网络阅读笔记(持续更新)

深度学习与神经网络阅读笔记&#xff08;持续更新&#xff09; 机器学习基础绪论人工智能主要领域可分为如下&#xff1a;人工智能的发展史&#xff1a;机器学习表示学习深度学习 线性模型Logistic回归Softmax回归感知器支持向量机总结对比 基础模型循环神经网络应用到机器学习…

MongoTemplate手动动态创建(简版)

1、背景 最近遇到一个需求&#xff0c;就是动态获取springboot中MongoTemplate&#xff0c;有哪些mongo数据库在项目启动的时候不确定&#xff0c;运行过程中有可能会增加&#xff0c;也有可能减少。只能通过一个接口获取所有mongo数据库的地址。但是springboot本身提供的mong…

panda3d 模型转换命令复习学习

在此学习了把maya模型转换为panda3d的egg格式&#xff1b; 在Panda3d中转换Maya模型为egg格式并使用pview查看_panda3d egg文件浏览器_bcbobo21cn的博客-CSDN博客 下面继续看一下模型转换命令&#xff1b;列出带 egg 字符串的命令&#xff1b; 先复习一下&#xff0c;可以把m…

Java -- XXL-JOB分布式任务调度平台

XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用 xxl是xxl-job的开发者大众点评的【许雪里】名称的拼音开头 官网地址 分布式任务调度平台XXL-JOB 文档地址…

响应数据加密解决方案

需求分析 响应数据加密是一种很重要的安全措施,可以保护数据在传输过程中不被未经授权的用户拦截、窃取或篡改。以下是响应数据加密需求分析: 响应数据必须进行加密: 所有响应数据必须进行加密,以保证数据在传输过程中的安全性。服务器可以采用HTTPS协议对响应数据进行加密…

剑指 Offer 46: 把数字翻译成字符串

这道题先画模型 假设3个数&#xff0c;第一个第二个可以组&#xff0c;第二个第三个可以组。所以有3种 123 && 字母3 && 1字母 当发现有两种操作方法&#xff0c;说明当前方法出错误了&#xff0c;必须立即想别的办法&#xff01; 除了使用一直除外&#xff…

ad18报错:net antennae:track

画了板子之后发现有这个错误提示&#xff0c;看了图&#xff0c;发现是在一个焊盘下面有2根残留的线&#xff0c;而且线边上出现了天线标志 net antennae的含义是网络天线&#xff0c;这里可以理解为板卡上某个网络的布线形成了天线&#xff0c;但是没有特别标注这一部分是天线…

【Mysql】MySQL体系结构,InnoDB、MyISAM存储引擎,索引结构、分类、语法、性能分析

1. MySQL体系结构 连接层 主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 服务层…

(五)Web_Server+网页可视化展示

第一步&#xff1a;先使用nodeJS获取mqtt转发的数据&#xff1a;添加链接描述 第二步&#xff1a;使用fs库&#xff0c;将数据存入txt文件(接上一步,这里没处理数据格式&#xff0c;只是测试) var fsrequire("fs");const mqtt require(mqtt) //存储订阅的消息 var …

Android ConstrainLayout布局中View位置的介绍与使用

一、介绍 ConstrainLayout是一款布局View&#xff0c;再Design库中&#xff0c;现已被大家广泛接受并使用。ConstrainLayout的布局采用的方式和其他都不同&#xff0c;他的对其方式是类似RelativeLayout&#xff0c;但是和RelativeLayout有明显的区别。 在布局渲染的时候&#…

获取Xilinx FPGA芯片IDCODE的4种方法(支持任何FPGA型号)

文章目录 方式1&#xff1a;官方文档方式2&#xff1a;一个头文件方式3&#xff1a;BSDL文件方法4&#xff1a;芯片IDCODE在线搜索网站Xilinx FPGA部分型号IDCODE汇总 方式1&#xff1a;官方文档 对于常用的Spartan-6系列可以在UG380文档中找到对应的IDCODE&#xff0c;Sparta…

CM+CDH 构建企业大数据平台

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…