最新C语言进阶:文件操作_extern _armabi,网络安全源码剖析之Framwork层消息传递

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

例如:D:\code\data.txt。 方便起见,文件标识通常成为文件名。如图:

文件类型

根据数据的组织形式,数据文件被分为两种:文本文件或者二进制文件。

  • 二进制文件:数据在内存中以二进制的形式存储,再直接输出到外存,就是二进制文件。
  • 文本文件:数据转换成ASCII码的形式再存储到外存中,就是文本文件。

如上图所示,test.c打开后可以看懂,则是文本文件,*.exe打开后显示乱码,则是二进制文件。

数据的存储

数据在内存中存储时,字符一律以ASCII码的形式存储,而数值可以以ASCII码的形式也可以以二进制的形式存储。

例有整数10000,若以ASCII码的形式存储,则5个字符共需5个字节。若以二进制的形式存储,则转化成补码,整型数据共需4个字节。

使用下列代码,将10000以二进制的形式存入文件data.txt中。

int main() {
	FILE\* pf = fopen("data.txt", "wb");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	int a = 10000;
	fwrite(&a, 4, 1, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

我们用二进制编辑器查看以二进制形式写入文件的10000,可以看到如下现象:可以按照如下推理得出答案。

//1.
00000000 00000000 00100111 00010000 - 10000原码
//2.c
00010000 00100111 00000000 00000000 - 小端存储
//3.
1   0    2   7    0   0    0   0    - 转化成十六进制 
10 27 00 00

文件缓冲区

C标准规定采用**“缓冲文件系统”处理数据文件,缓冲文件系统即是系统自动为程序所使用每一个文件开辟一块“文件缓冲区”**。

  1. 从内存向外存输出数据会先经过输出缓冲区,装满输出缓冲区后才一起输送到外存。同样,
  2. 从外存向内存输入数据会先经过输入缓冲区,装满输入缓冲区后再一起输入到内存。

缓冲区的大小由编译系统决定,具体多少算“满”,C语言阶段不深入研究。

二者之间传递数据的操作是由程序调起操作系提供的输入输出的接口完成的。目的是使之不会频繁地传输打断操作系统。

文件信息区

缓冲文件系统中,有个关键的概念叫“文件类型指针”,简称“文件指针”。

当程序操作一个文件的时候,都在内存中开辟了一个与该文件相对应的文件信息区,用于存放文件的相关信息(如文件名称,状态,位置等)。这些信息都是一个结构体的成员,该结构体类型由系统声明,取名为"FILE"。

每一个文件被操作时,都会先创建好一个文件信息区,所谓文件信息区其实就是一个被封装好的结构体类型所创建的变量,该变量与所属文件强关联。操作文件其实就是操作文件信息区,打开文件其实返回了文件信息区的地址。如图:

从内存读取方式中也可窥探一番,内存中数据也是一级一级读取的,先将内存中的数据提至缓存区,再放到寄存器中。读取文件也是这样的逻辑,不然直接读取整个文件,加载慢占存大也容易出错。

vs2013中仍可以看到文件信息区的结构体封装内容,可以看出都是文件的相关信息。文件信息区就是FILE类型的结构体变量

文件指针

这些变量都是由系统封装好自动创建的,不必关注细节。一般都是通过FILE*的指针来维护该FILE结构体变量,这就是文件指针。

FILE\* pf;//指向文件信息区的指针

通过FILE类型的结构体指针变量pf,可指向某个文件信息区从而操作该文件。如图:

文件的开关操作

想要通过文件指针进行文件操作,必须先打开文件,使用结束后关闭文件。操作文件的步骤分为:1. 打开文件 2. 读写文件 3. 关闭文件。

C语言标准规定,使用fopenfclose来打开和关闭文件。

文件的打开 fopen
函数声明
FILE\* fopen (const char\* filename, const char\* mode);

Return Value
This function returns a pointer to the open file. A null pointer value indicates an error. 

Parameters
1. filename - Filename
2. mode - Type of access permitted

Remarks
The fopen function opens the file specified by filename.

fopen函数以mode的方式打开名为filename的文件,并返回文件信息区的起始地址。

函数用法
  • 打开文件以读还是写的方式由mode决定。打开方式如下:
模式方式含义备注
“r”只读输入数据,打开已存在的文本文件文件不存在,则调用失败
“w”只写输出数据,“新建”一个文本文件文件已存在,则销毁内容
“a”追加输出数据,向文本文件末尾添加数据文件不存在,则创建文件
“rb”只读输入数据,打开已存在的二进制文件文件不存在,则调用失败
“wb”只写输出数据,“新建”一个二进制文件文件已存在,则销毁内容
“ab”追加输出数据,向二进制文件末尾添加数据文件不存在,则创建文件
“r+”读写兼具输入输出,打开已存在的文本文件文件不存在,则调用失败
“w+”读写兼具输入输出,“新建”一个文本文件文件已存在,则销毁内容
“a+”读加兼具输入输出,向文本文件末尾添加数据文件不存在,则创建文件
  • 文件名filename可采用相对路径即解决方案目录下文件夹和绝对路径即文件路径+文件名主干+后缀。
//打开文件
//1. 绝对路径
FILE\* pf = fopen("C:\\Users\\w3395\\Desktop\\data.txt", "w");
//2. 相对路径
FILE\* pf = fopen("data.txt", "w");

文件的关闭 fclose
函数声明
int fclose (FILE\* stream);

Return Value
fclose returns 0 if the stream is successfully closed.

Parameter
1. stream - Pointer to FILE structure

Remarks
The fclose function closes stream.

fclose函数关闭对文件信息区的输入输出流。

函数用法
  • fclose仅关闭了关于文件的输入输出流,不会将文件指针置空。为防止出现野指针,需置空文件指针。
int main() {
	//打开文件
	FILE\* pf = fopen("data.txt", "w");
	//打开失败
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	//操作文件
	//...
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件的读写操作
流的定义

“流是磁盘或其它外围设备中存储的数据的源点或终点” —— 《C语言程序设计》

流主要是指一种逻辑上的概念,产生数据的叫输入流,消耗数据的叫输出流。至于产生和消耗,因设备不同而有所差异,但C语言中对它们一视同仁,以“流”代之。

将字符放入文件中,或打印到屏幕上,这里的文件和屏幕就是外部设备。如屏幕、网络、文件,硬盘都是外部设备。不同设备的读写方式肯定不一样,为方便起见,故抽象出“流”的概念,以一个“流”字来概括它们的特征。故可把流看作是一种数据的载体,通过它可以实现数据交换和传输,传递数据的方式由“流”决定。我们仅需将数据放入“流”当中即可。

程序与数据的交互是以“流”的形式进行的。对象间进行数据的交换时总是先将数据转换为某种形式的流,再通过流的传输,到达目标对象后再将流转换为对象数据。C语言中文件读写时,都会先进行“打开文件”操作,这个操作就是在打开数据流,而“关闭文件”操作就是关闭数据流。

当我们使用printf,scanf时即是通过标准输入输出流在屏幕键盘和程序之间传递的。一般程序中会有三种流:标准输出流stdout,标准输入流stdin,标准错误流stderr,三种流都是FILE*的指针。

文件的顺序读写

下列是成对的,顺序读取和写入操作函数,分别适用于不同类型的数据。所有输出流包括文件输出流和标准输出流。

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

字符输入输出 fputc&fgetc
函数声明
int fputc (int c, FILE\* stream);

Return Value
This function returns the character written. 

Parameters
1. c - Character to be written
2. stream - Pointer to FILE structure

Remarks
This function writes the single character c to a file at the position pointed by the associated file position pointer (if defined) and advances the pointer appropriately(适当). 

int fgetc (FILE\* stream);

Return Value
fgetc return the character read as an int or return EOF to indicate an error or end of file. 

Parameter
stream - Pointer to FILE structure

Remarks
This function reads a single character from the current position of a file; The function then increments(递增) the associated file pointer (if defined) to point to the next character.

fputc将字符c放到文件指针stream所指向的文件中。

fgetc返回文件指针所指向的字符。

函数用法
  • fputc每写入一个字符文件指针就向后移动一个字符的位置。fgetc每读取一个字符文件指针就向后移动一个字符的位置。
  • fputc适用于所有输出流,可以输出到任意设备上。fgetc同样适用于所有输入流,可以从任意设备上读取数据。
int main() {
	FILE\* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);	
	fclose(pf);
	pf = NULL;
	return 0;
}
int main() {
	FILE\* pf = fopen("data.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	int ch = fgetc(pf);
	printf("%c ", ch);
	ch = fgetc(pf);
	printf("%c ", ch);
	ch = fgetc(pf);
	printf("%c ", ch);
	fclose(pf);
	pf = NULL;
	return 0;
} 

//标准输出流
fputc('b', stdout);
fputc('i', stdout);
fputc('t', stdout);
//标准输入流
printf("%c\n", fgetc(stdin));
printf("%c\n", fgetc(stdin));
printf("%c\n", fgetc(stdin));

字符串输入输出 fputs&fgets
函数声明
int fputs (const char\* string, FILE\* stream);

Return Value
This function returns a nonnegative(非负) value if it is successful. On an error, fputs returns EOF.

Parameters
1. string - Output string
2. stream - Pointer to FILE structure

Remarks
This function copies string to the output stream at the current position.

char\* fgets (char\* string, int n, FILE\* stream);

Return Value
This function returns string. NULL is returned to indicate an error or an end-of-file condition.

Parameters
1. string - Storage location for data
2. n - Maximum number of characters to read
3. stream - Pointer to FILE structure

Remarks
The fgets function reads a string from the input stream argument and stores it in string. fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first. The result stored in string is appended with a null character. The newline character, if read, is included in the string. 

fputc将字符串string放到文件指针stream所指向的文件中。

fgetsstream文件中指向的字符串的前n-1个字符放入string中,并以返回值的形式返回。

函数用法
  • fputs一次写入一行,若需换行可以加上\n,文件指针移动到末尾。
  • fgets每次只读取规定字符数

n

1

n-1

n−1 个字符最后第

n

n

n 个字符为\0作为字符串结束标志。

  • fputs适用于所有输出流,可以输出到任意设备上。fgets同样适用于所有输入流,可以从任意设备上读取数据。
int main() {
	FILE\* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	fputs("hello world!\n", pf);
	fputs("hello bit!\n", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}
int main() {
	FILE\* pf = fopen("data.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	char arr[20] = { 0 };
	fgets(arr, 5, pf);
	printf("%s\n", arr);
	fgets(arr, 5, pf);
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

格式化输入输出 fprintf&pscanf
函数声明
int fprintf (FILE\* stream, const char\* format [, argument ]...);

Return Value
fprintf returns the number of bytes written. This function returns a negative value instead when an output error occurs. 

Parameters
1. stream - Pointer to FILE structure
2. format - Format-control string
3. argument - Optional arguments

Remarks
fprintf formats(格式化) and prints all characters and values to the output stream. Each argument(参数) is converted(转换) and output according to the corresponding format specification(规范). For fprintf, the format argument has the same syntax(语法) that it has in printf.

int fscanf (FILE\* stream, const char\* format [, argument ]...);

Return Value
This function returns the number of fields(字段数) successfully converted(转化) and assigned(分配); 

Parameters
1. stream - Pointer to FILE structure
2. format - Format-control string
3. argument - Optional arguments

Remarks
The fscanf function reads data from the current position of stream into the locations given by argument (if any). It has the same form and function as the format argument for scanf;

fprintf,fscanf是以格式化的形式,例如:"%d,%f",a,f,输出输入到所有输入输出流。

函数用法
  • fprintf,fscanf和 printf,scnaf 的参数差别仅是前面带有文件指针pf,故写好 printf,scanf 的形式再在参数列表最前添上文件指针pf。如:
struct S {
	int a;
	char c;
	double d;
};
int main() {
	FILE\* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	struct S s = { 100,'w',3.14 };
	fprintf(pf, "%d %c %lf", s.a, s.c ,s.d);

	return 0;
}
int main() {
	FILE\* pf = fopen("data.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return -1;
	}
	struct S s = { 0 };
	fscanf(pf, "%d %c %lf", &s.a, &s.c, &s.d);
	printf("%d %c %lf", s.a, s.c, s.d);
	return 0;
}

  • fprintf适用于所有输出流,可以输出到任意设备上。fscanf同样适用于所有输入流,可以从任意设备上读取数据。

以上有适用于单个字符的,适用于字符串的以及适用于任意格式的字符,字符串,格式化输入输出函数。但都是文本形式的输入输出函数,接下来的是以二进制的形式的输入输出函数。

二进制输入输出 fwrite&fread
函数声明
size\_t fwrite (const void\* buffer, size\_t size, size\_t count, FILE\* stream);

Return Value
fwrite returns the number of full items actually written.

Parameters
1. buffer - Pointer to data to be written(指向待写数据的指针)
2. size - Item size in bytes(元素宽度)
3. count - Number of items to be written(元素个数)
4. stream - Pointer to FILE structure(文件指针)

Remarks
The fwrite function writes up to count items, of size length each, from buffer to the output stream. The file pointer associated with stream (if there is one) is incremented by the number of bytes actually written. 

size\_t fread (void\* buffer, size\_t size, size\_t count, FILE\* stream);

Return Value
fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. 

Parameters
1. buffer - Storage location for data
2. size - Item size in bytes
3. count - Maximum number of items to be read
4. stream - Pointer to FILE structure

Remarks
The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read.

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

😝朋友们如果有需要的话,可以联系领取~

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

2️⃣视频配套工具&国内外网安书籍、文档
① 工具

② 视频

image1

③ 书籍

image2

资源较为敏感,未展示全面,需要的最下面获取

在这里插入图片描述在这里插入图片描述

② 简历模板

在这里插入图片描述

因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值