【C语言】—— 文件操作(下)

  

前言:

  
  
  在 【C语言】—— 文件操作(上) 一文中,我们对文件有了一个简单的了解,并学会了如何打开和关闭文件,下面就让我们一起来学学如何对文件进行读写吧。
  
  

五、文件的顺序读写

5.1、 顺序读写函数介绍

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

  注:上面说的适用于所有输入流一般指适用于标准输入流和其他输入流(如文件输入流);所有输出流一般指适用于标准输出流和其他输出流(如文件输出流)

  下面我们对上述函数一一进行介绍
  

5.2、 f p u t c fputc fputc 函数

在这里插入图片描述

  • 函数功能将一个字符写入流中,这个流其实就是文件流
  • 函数参数
    • i n t int int c h a r a c t e r character character要写入的字符,字符的本质就是 A S C I I ASCII ASCII 码值,因此这里参数类型为 i n t int int 没有问题
    • F I L E FILE FILE * s t r e a m stream stream :指向要写入文件的文件指针
  • 返回类型:返回类型是 int:当写入成功,返回写入的值,当写入失败,返回EOF(-1)
      

函数使用:

#include<stdio.h>

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

	//写文件
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	//写入26个字母
	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

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

在这里插入图片描述

  这样,字符就写好了。
  
  当写入字符时,还有一些细节需要注意:当一个文件打开时,最开始其实是有一个光标指向第一个位置,每当用 f p u t c fputc fputc 函数写入一个字符光标则后退一格。光标是用来维护此时此刻我们这个文件写到哪的,而且是按照一定的顺序往后走的,因此叫做顺序读写

  

5.3、 f g e t c fgetc fgetc 函数

在这里插入图片描述

  • 函数功能:从流(文件)中获取一个字符
  • 返回值:返回类型为 i n t int int 。如果成功,就会将读到的字符返回,如果读取失败或者遇到文件末尾返回EOF(-1)
    • 为什么返回类型是 int 呢?正是因为它会返回两种类型的值:字符的 A S C I I ASCII ASCII码 值EOF;如果返回类型为 char,则 EOF 无法返回
        

函数使用:

#include<stdio.h>

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

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

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

运行结果:

在这里插入图片描述

  而同样,以只读的方式打开文件,刚开始光标是在第一个位置,即指向 a a a每读一个字符,光标向后退一位

  

5.4、 f p u t s fputs fputs 函数

在这里插入图片描述

  • 函数功能将 str 字符串写入文件流中,直至遇到 ‘\0’ 停止(‘\0’不会被写入)

   注:多次调用该函数,并不会实现主动换行,要想换行应主动输入‘\n’
  
函数使用:

#include<stdio.h>

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

	//写文件
	fputs("hello", pf);
	fputs("world\n", pf);
	fputs("hello csdn\n", pf);

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

	return 0;
}

运行结果:
在这里插入图片描述
  我们可以看到,加了换行符后,文件的光标是直接落到下一行的。

  

5.5、 f g e t s fgets fgets 函数

在这里插入图片描述

  • 函数功能从流中最多读取 num 个字符,并放在 str 所指向的空间中
    • 函数读 n u m num num 个字符,但是最多只能读取 n u m num num - 1个,因为最后一个位置函数会自己加上 ‘\0’
    • 该函数不会换行读取。当 n u m num num 大于字符数时,遇到换行符 ‘\n’,将 ‘\n’ 读取后,不再往下读取,自己加上 ‘\0’ 后停止。
    • 当函数读取成功,返回的是目标空间的地址;读取失败则返回空指针(NULL)

  
函数使用:

#include<stdio.h>

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

	//读文件
	char arr1[10] = "xxxxxxxxx";
	fgets(arr1, 8, pf);

	char arr2[10] = "xxxxxxxxx";
	fgets(arr2, 8, pf);


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

	return 0;
}

运行结果:

在这里插入图片描述

  

5.6、 f p r i n t f fprintf fprintf 函数

在这里插入图片描述

  
  该函数的功能是将数据以格式化的形式写入流中(以文本的形式)
  
  其实, f p r i n t f fprintf fprintf 函数 p r i n t f printf printf 函数是非常相像的,让我们来对比一下
  

在这里插入图片描述

  
  他们的区别仅仅是第一个参数的有无而已,其他都是一模一样的,所以你会用 p r i n t f printf printf你就会用 f p r i n t f fprintf fprintf
  
  多的一个参数是什么呢?是文件流,你需要将数据输出到的那个文件流
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };

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

	//写文件
	fprintf(pf, "%s %d %f", s.name, s.age, s.score);

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

运行结果:
在这里插入图片描述
  

5.7、 f s c a n f fscanf fscanf 函数

在这里插入图片描述

  
  该函数的功能是从文件流中读取格式化的数据。
  
  不难发现, f s a n f fsanf fsanf s c a n f scanf scanf 函数很像,我们来对比一下

  

在这里插入图片描述

  
  同 f p r i n t f fprintf fprintf 一样, f s c a n f fscanf fscanf s c a n f scanf scanf 只是相差一个参数而已,你会用 s c a n f scanf scanf 自然也就会用 f s c a n f fscanf fscanf 函数,第一个参数即是你所要读取的文件流
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };

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

	//读文件
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
	//printf("%s %d %.2f\n", s.name, s.age, s.score);
	fprintf(stdout, "%s %d %.2f\n", s.name, s.age, s.score);
	
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

  
运行结果:

在这里插入图片描述

  注意看,上述代码用了 f p r i n t f fprintf fprintf 来将数据打印在屏幕上

  还记得最开始的表格中, f p r i n t f fprintf fprintf 最后一列写的是所有输出流吗?这所有输出流就包括了文件流标准输出流,既然 f p r i n t f fprintf fprintf 可以输出到文件中,那么自然也就可以输出到屏幕中,完成 p r i n t f printf printf 一样的功能。

  而同理,前面讲的 f p u t c fputc fputc f g e t s fgets fgets f s c a n f fscanf fscanf 等函数也可以从标准输入(输出)流中获取(输出)数据。

  

5.8、 p r i n t f / f p r i n t f / s p r i n t f printf/fprintf/sprintf printf/fprintf/sprintf 函数对比

  
通过我们前面的学习,我们已经知道了 p r i n t f printf printf f p r i n t f fprintf fprintf 函数的作用:

  • p r i n t f printf printf:把数据以格式化的形式打印在标准输出流
  • f p r i n t f fprintf fprintf : 把数据以格式化的形式打印在 指定的输出流

那么 s p r i n t f sprintf sprintf 函数又是作什么的呢?我们一起来看看

在这里插入图片描述

  
  该函数的作用是:将数据以格式化的形式写到字符串。其实就是把格式化的数据转换成字符串
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };
	char buf[50] = { 0 };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	printf("%s\n", buf);
	return 0;
}

运行结果:
在这里插入图片描述
  该代码完全是以 %s 的形式打印的,说明数据已经完全转换成字符串了。

  

5.9、 s c a n f / f s c a n f / s s c a n f scanf/fscanf/sscanf scanf/fscanf/sscanf 函数对比

  同样,通过我们前面的学习,我们已经知道了 s c a n f scanf scanf f s c a n f fscanf fscanf 函数的作用:

  • s c a n f scanf scanf:从 标准输入流 中读取格式化的数据
  • f s c a n f fscanf fscanf:从 指定输入流 中读取格式化的数据

  那 s s c a n f sscanf sscanf 的功能又是什么呢?学习了 s p r i n t f sprintf sprintf ,我们猜测,其应该是从字符串中读取格式化数据,是不是呢?我们一起来看看
  

在这里插入图片描述

  
函数功能从字符串中读取格式化数据
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };
	char buf[50] = { 0 };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	
	struct S a = { 0 };
	sscanf(buf, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %f\n", s.name, s.age, s.score);
	return 0;
}

运行结果:

在这里插入图片描述

  
  

5.10、 f w r i t e fwrite fwrite 函数

在这里插入图片描述

  • 函数功能:以二进制的形式将内存块中的数据入文件中
  • 参数介绍
    • c o n s t const const v o i d void void * p t r ptr ptr p t r ptr ptr 是指向要写入数据的数组的指针
    • s i z e size size_ t t t s i z e size size:表示要写入的每个元素的大小
    • s i z e size size_ t t t c o u n t count count:表示要写入元素的个数

  
下面我们直接上代码:

#include<stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);

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

	fwrite(arr, sizeof(arr[0]), sz, pf);


	fclose(pf);
	pf = NULL;
	return 0;
}

  
我们以二进制的方式打开:

在这里插入图片描述

  

5.11、 f r e a d fread fread 函数

在这里插入图片描述

  该函数的作用是:以二进制的形式读取数据到内存中

  我们可以看到,这函数的参数与 f w r i t e fwrite fwrite 是大同小异的,这里就不一一介绍了,我们直接上代码

#include<stdio.H>

int main()
{
	int arr[5] = { 0 };

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

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

	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

在这里插入图片描述

  但是,上面代码是我提前知道了总共的数据个数,当我不知道数据具体个数是又该怎么办呢?

  这里,我们需要知道 f r e a d fread fread 函数的返回值,该函数的返回值是读取到的数据的个数。这时,当我要求读 7 个数据,而返回值是 5 时,说明数据读完了。

  上面的代码我们可以做如下修改:

#include<stdio.h>

int main()
{
	int arr[5] = { 0 };

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

	int i = 0;
	while (fread(arr + i, sizeof(arr[0]), 1, pf))
	{
		printf("%d ", arr[i]);
		i++;
	}
	printf("\n");

	fclose(pf);
	pf = NULL;
	return 0;
}

  
  

六、文件的随机读写

  前面我们所学习到的函数都是顺序读写,光标是依次往后移动。那能不能做到随机读写呢,即我想在哪里读写就在哪读写,指那打那。

  当然是可以的,下面让我们一起来学习。
  

6.1、 f s e e k fseek fseek 函数

在这里插入图片描述

  • 功能:根据文件指针的位置和偏移量来定位文件指针(光标)
  • 参数介绍
    • l o n g long long i n t int int o f f s e t offset offset:相对于起始位置的偏移量,可正可负
    • i n t int int o r i g i n origin origin起始位置

起始位置选择:

常量所指位置
SEEK_SET文件的起始位置
SEEK_CUR当前光标位置
SEEK_END文件结尾

  
  这个函数有什么用呢?比如文件中有 a b c d e f g abcdefg abcdefg 的数据,当前光标指向 a a a,而我想直接读 e e e,这时就可以用该函数移动光标啦。
  

在这里插入图片描述

例子:

#inclu<stdio.h>

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

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

	fseek(pf, 3, SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n", ch);

	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

在这里插入图片描述

  
  

6.2、 f t e l l ftell ftell 函数

在这里插入图片描述

f t e l l ftell ftell 函数会返回文件指针(光标) 相对于文件起始位置的 偏移量

  这里,我们想:如果我们让光标读到文件末尾,在返回偏移量,是不是就能知道文件的长度呢?答案是肯定的。
  
例子:

#includ<stdio.h>

int main()
{
	FILE* pf;
	long size;
	pf = fopen("test.txt", "rb");
	if (NULL == pf)
		perror("Error opening file");
	
	fseek(pf, 0, SEEK_END); // non-portable
	size = ftell(pf);
	fclose(pf);
	printf("Size of test.txt: %ld bytes.\n", size);
	
	return 0;
}

  
  

6.3、 r e w i n d rewind rewind 函数

在这里插入图片描述

   r e w i n d rewind rewind 函数可以让文件指针回到起始位置

  走的太远,别忘了回头路

例子:

#include<stdio.h>

int main()
{
	int n;
	FILE* pf;
	char buffer[27];
	pf = fopen("test.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
	{
		fputc(n, pf);
	}
	rewind(pf);
	fread(buffer, 1, 26, pf);
	fclose(pf);
	buffer[26] = '\0';
	printf(buffer);
	return 0;
}

  
  

七、文件读取结束的判定

7.1、 被错误使用的 f e o f feof feof

  
  很多人都以为 f e o f feof feof函数是用来直接判断文件读取是否结束。其实这是大错特错的
   f e o f feof feof 的作用是:当文件读取结束时,判断读取结束的原因是否是因为:遇到文件末尾结束

  现在假设文件读取结束了,但是是什么原因读取结束的呢?

  1. 有可能遇到文件末尾
  2. 读取的时候发生了错误

   f e o f feof feof 函数是判断是否是因为遇到文件末尾而结束的。
  而还有个函数叫 f e r r o r ferror ferror 是用来判断是否是因为遇到错误而读取结束的
  

  其实在我们打开一个流时,会有两个标记值

  1. 是否遇到文件末尾
  2. 是否发生错误
      

  当读文件的过程中确实是遇到文件末尾了,就会将第一个值标记;遇到错误就会将第二个值标记
   f e o f feof feof是用来检测第一个标记的; f e r r o r ferror ferror是用来检测第二个标记

f e o f feof feof 函数:当文件确实是因为读取到文件末尾而结束时,返回一个非零值,反之返回 0
  
  

7.2、如何判断文件读取结束

  那么如何来判断文件是否读取结束呢?其实在前面结束各个函数时已经顺便介绍了:通过函数的返回值进行判断!
  

(1)文本文件判断

函数名正常读取返回值读取结束或遇到错误的返回值
fgetc返回读取到的字符的ASCII码值EOF
fgets返回目标空间的地址NULL

  

(2)二进制文件判断

  二进制文件用 f r e a d fread fread 进行读取, f r e a d fread fread 返回值是其读取到的个数。当其返回值小于实际要读取的个数时,表示文件读取结束

  

八、 文件缓冲区

  我们想一个问题:当我们想往文件中存 26 个字母,这 26 个字母是直接从程序(内存)中存到文件(硬盘)中的吗?
  其实不是的。

  ANSI C 标准采用 “缓冲文件系统” 处理的数据文件的,所谓缓冲文件系统指的是系统自动在内存中为程序中为每一个正在使用的文件开辟一块“文件缓冲区”

  从内存向磁盘输出数据会先送达内存中的缓冲区装满缓冲区主动刷新缓冲区才将数据送到磁盘上。

  如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区或刷新缓冲区),然后在从缓冲区逐个地将数据送到程序数据区(程序变量等)。

  缓冲区的大小根据C编译系统决定的。

在这里插入图片描述

  那为什么要有文件缓冲区呢?

  其实,当我们向文件中输入输出数据时,相关函数会调用操作系统相关接口;这时如果写一个字符就调用一次操作系统,是不是效率太低,并且我们的操作系统上面可不止跑着一个程序,这时你一直打扰操作系统,操作系统就没法干活了。
  应用缓冲区,在缓冲区攒够一定数据再一次性全部录进,效率就会提升很多

  下面,我们通过一段代码验证缓冲区的存在:

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

  这里我们需要注意:

  因为有文件冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件

  如果不做,可能导致读写文件的问题
  
  
  
  


  好啦,本期关于文件操作的知识就介绍到这里啦,希望本期博客能对你有所帮助。同时,如果有错误的地方请多多指正,让我们在C语言的学习路上一起进步!

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

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

相关文章

html+css+js淘宝商品界面

点击商品&#xff0c;alert弹出商品ID 图片使用了占位符图片&#xff0c;加载可能会慢一点 你可以把它换成自己的图片&#x1f603;源代码在图片后面 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"…

Word “当前页“ 与 “前一页“ (含部分内容)间有大半页空白,删除空白方法

鼠标光标选中需要向上移的句子&#xff0c;右键点击“段落”&#xff0c;然后在跳出的窗口中按照“换行和分页”中的红色方框内取消勾选后&#xff0c;点击确定即可。

金斗云 HKMP智慧商业软件 任意用户创建漏洞复现

0x01 产品简介 金斗云智慧商业软件是一款功能强大、易于使用的智慧管理系统,通过智能化的管理工具,帮助企业实现高效经营、优化流程、降低成本,并提升客户体验。无论是珠宝门店、4S店还是其他零售、服务行业,金斗云都能提供量身定制的解决方案,助力企业实现数字化转型和智…

Proteus-51单片机-DS18B20多点测温

DS18B20多点测温 一、Proteus仿真演示 每个DS18B20都有一个唯一的64位序列号,这使得在同一总线上可以挂载多个传感器,无需额外的地址分配。主机(通常为单片机)通过特定的时序控制,可以依次读取各个DS18B20的温度数据,实现分布式测温。 二、代码特点 三、开发环境介绍 本…

【unity实战】使用unity的新输入系统InputSystem+有限状态机设计一个玩家状态机控制——实现玩家的待机 移动 闪避 连击 受击 死亡状态切换

最终效果 文章目录 最终效果前言人物素材新输入系统InputSystem的配置动画配置代码文件路径状态机脚本创建玩家不同的状态脚本玩家控制源码完结 前言 前面我们已经写过了使用有限状态机制作一个敌人AI&#xff1a;【unity实战】在Unity中使用有限状态机制作一个敌人AI 那么玩…

收银系统源码分享-PHP可二开

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 私有化独立…

面向对象-封装

一.包 1.简介 当我们把所有的java类都写src下的第一层级&#xff0c;如果是项目中&#xff0c;也许会有几百个java文件。 src下的文件会很多&#xff0c;开发的时候不方便查找&#xff0c;也不方便维护如果较多的文件中有同名的&#xff0c;十分麻烦 模块1中有一个叫test.ja…

Nuxtjs3教程

起步 官方文档 官方目录结构 安装 npx nuxi@latest init <project-name>后面跟着提示走就行 最后yarn run dev 启动项目访问localhost:3000即可 路由组件 app.vue为项目根组件 <nuxt-page />为路由显示入口 将app.vue更改内容如下 <template><d…

WPS中制作甘特图的详细教程

网上没几个详细说怎么在WPS中制作甘特图的&#xff0c;我自己整理了一下详细教程&#xff0c;最终效果如下图所示&#xff1a; 1.写好需要展示的项目相关信息&#xff0c;如下图所示&#xff1a; #####这个进度的百分比渐变效果这样设置就行了 2.现在我们需要计算已用时间和剩…

lodash中flush的使用(debounce、throttle)

在项目的配置中&#xff0c;看到了一个请求&#xff0c;类似是这样的 import { throttle } from lodash-es// 请求函数 async function someFetch(){const {data} await xxx.post()return data }// 节流函数 async function throttleFn(someFetch,1000)// 执行拿到数据函数 a…

Zabbix 配置MySQL数据库监控

Zabbix MySQL数据库监控简介 通过 Zabbix 监控 MySQL 数据库&#xff0c;可以获取有关数据库性能、运行状况和资源使用情况的详细信息&#xff0c;帮助及时发现和解决问题。 Zabbix官方提供了一个名为MySQL by Zabbix agent的监控模板&#xff0c;该模板专为 Zabbix 通过 Zabb…

Java中的文件IO

文件,我们之前在C语言中接触过,是在硬盘上存储数据的方式,操作系统帮我们把硬盘的一些细节都封装起来了,因此在这里我们只需要了解文件的相关接口即可. 首先硬盘是用来存储数据的,和内存相比,硬盘的存储空间更大,访问速度更慢,成本更低,可以实现持久化存储,而操作系统通过&quo…

Polkadot 安全机制揭秘:保障多链生态的互操作性与安全性

作者&#xff1a;Filippo Franchini&#xff0c;Web3 Foundation 原文&#xff1a;https://x.com/filippoweb3/status/1806318265536242146 编译&#xff1a;OneBlock Polkadot 是一个创新的多链区块链平台&#xff0c;旨在实现不同区块链之间的互操作性和共享安全性。本文将详…

c++习题02-浮点数求余

目录 一&#xff0c;问题 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;问题 二&#xff0c;思路 虽然在浮点类型中没有取余的运算&#xff08;无法直接使用%符号取余&#xff09;&#xff0c;但是我们都知道在数学中&#xff0c;除法是减法的连续运算&#xff…

软件测试最全面试题及答案整理(2024最新版)

1、你的测试职业发展是什么? 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&#xff0c;不断…

师从IEEE fellow|博士后加拿大阿尔伯塔大学成行

V老师指定申请加拿大&#xff0c;优先对方出资的博士后&#xff0c;如果外方无资助&#xff0c;也可以自筹经费&#xff0c;但要求必须是博士后头衔。最终我们为其落实了加拿大阿尔伯塔大学的postdoctoral fellow&#xff08;博士后研究员&#xff09;&#xff0c;尽管是无薪职…

经典链表算法题:找到环的入口。清晰图示推导出来

Leetcode题目链接 原理 重画链表如下所示&#xff0c;线上有若干个节点。记蓝色慢指针为 slow&#xff0c;红色快指针为 fast。初始时 slow 和 fast 均在头节点处。 使 slow 和 fast 同时前进&#xff0c;fast 的速度是 slow 的两倍。当 slow 抵达环的入口处时&#xff0c;如…

前端播放RTSP视频流,使用FLV请求RTSP视频流播放(Vue项目,在Vue中使用插件flv.js请求RTSP视频流播放)

简述&#xff1a;在浏览器中请求 RTSP 视频流并进行播放时&#xff0c;直接使用原生的浏览器 API 是行不通的&#xff0c;因为它们不支持 RTSP 协议。为了解决这个问题&#xff0c;开发者通常会选择使用像 flv.js 这样的库&#xff0c;它专为在浏览器中播放 FLV 和其他流媒体格…

4款引以为豪的办公软件,使用起来,舒适度满满

Everything 是Windows神级搜索软件&#xff0c;能做到秒级响应。 Everything 之前小编在文章里提过好几次&#xff0c;但还有很多小伙伴不知道&#xff0c;那就再给大家种草一下哈。 只需要打开一次&#xff0c;Everything就会自动为你的文件建立索引&#xff0c;之后&#…

Spring MVC 中使用 RESTFul 编程风格

1. Spring MVC 中使用 RESTFul 编程风格 文章目录 1. Spring MVC 中使用 RESTFul 编程风格2. RESTFul 编程风格2.1 RESTFul 是什么2.2 RESTFul风格与传统方式对比 3. Spring MVC 中使用 RESTFul 编程风格(增删改查)的使用3.1 准备工作3.2 RESTFul 风格的 “查询” 所有&#xf…