【零基础C语言】文件操作

news2024/11/27 8:46:26

目录

 理解文件操作

 什么是文件

 程序文件

 数据文件

 文件名字

 二进制文件和文本文件

 文件的打开和关闭

 文件的打开和关闭操作

实验1,打开一个文件并且输入26个字母 

打开读取文件text.txt ,并且将它拷贝进text_cpy.txt 

使用 fputs 和 fgets 函数 

使用 fprintf函数和 fscanf 函数 

有关于流的概念

 使用 fwrite 和 fread 函数

文件的随机读写 - 适用于二进制文件

 fseek 函数

ftell 函数 

 rewind 函数

 文件读取结束的判定

文件缓冲区


 

 理解文件操作

 我们为什么要使用文件呢?

 1.可以长久的存储我们的数据,没有文件存储我们输入的程序代码数据是在电脑内存中存储的,但是程序结束后,我们的数据也会清空,无法持久化保存

如以下代码:

int main()
{
	int a = 0; //创建变量a
	scanf("%d", &a); // 向a中输入数值
	return 0;
}

 我们可以通过内存窗口看见int变量a中存放我们输入的值,但是程序结束,数据会清空,我们需要重新输入

 什么是文件

 文件指的就是磁盘上的文件
 但是程序中我们的文件分为两种:程序文件,数据文件 - 按照功能划分

 

 程序文件


 struct 程序文件
{
    1.源程序文件(后缀为.c);
  2.目标文件(windows环境后缀为.obj);
  3.可执行文件(windows环境后缀为.exe);
};

 数据文件


 该文件的内容不一定是程序,也可以是运行时读写的数据,比如程序运⾏需要从中读取数据的⽂件,或者输出内容的文件。


 文件名字


 用于用户识别和使用,是文件的标识,这个相信大家都不陌生,我们在打开磁盘可以在上方的小方块看到当期文件的名字。

 二进制文件和文本文件

根据数据不同形式,我们将数据文件划分为二进制文件和文本文件

二进制文件:以二进制的形式存储,不用转换直接可以输出到外存

文本文件:字符一律以ASCLL码值存储,需要转换才可以输出到外存
 

 文件的打开和关闭

 在了解文件之前,我们需要认识一种抽象的概念 - 流
 什么是流呢?我们在生活中获取消息是从人流,网上等等渠道,同理计算机也是如此,
 我们把从键盘输入,文件读写和其他所有外部的数据糅合起来比作一条流淌着字符的数据河,
 而计算机则是从河中获取所需要的数据,读取它们,然后打开,再操作数据

 那么我们有可能有疑问了?我们平时键盘输入代码,屏幕打印字符数据好像并没有使用流啊
 这里我们就需要引入一个概念 - 标准流


 标准流在计算机C程序运行启动时就默认打开了3个流:

  1. stdin  - 标准输入流,获取我们输入的信息。
  2. stdout - 标准输出流,输出我们需要打印的信息
  3. stderr - 标准错误流。

 有了以上默认打开的流,我们使用scanf和printf就可以进行输入输出操作

 stdin,stdout,stderr 类型为 FILE* - 文件指针
 C语⾔中,就是通过FILE*的⽂件指针来维护流的各种操作的。

 文件指针

 我们在打开使用文件时,内存中会开辟一个文件信息区,这个信息区用来存放文件的相关
 信息,这些信息是保存在一个结构体变量中,取名为FILE。

 如vs2013编译环境中#include <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* pf; 文件指针变量


 文件的打开和关闭操作

 在读写编辑文件之前,我们需要学会如何打开和关闭文件

 1.打开文件

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

 ANSIC规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件

 代码演示:

 打开文件:
FILE* fopen(const char* filename, const char* mode);

 关闭文件:
int fclose(FILE* stream);

 mode - 文件打开的模式,所有模式如下:

 "r"(只读) - 输入数据,打开一个存在的文本文件 - 如果文件不存在(出错)

 "w"(只写) - 输出数据,打开一个文本文件 - 如果文件不存在(创建一个新的文件)

 "a"(追加) - 向文本文件末尾添加数据 - 如果文件不存在(创建一个新的文件)

 "rb"(只读) - 输入数据,打开一个二进制文本文件 - 如果文件不存在(出错)

 "wb"(只写) - 输出数据,打开一个二进制文本文件 - 如果文件不存在(创建一个新的文件)

 "ab"(追加) - 向二进制文本文件末尾添加数据 - 如果文件不存在(创建一个新的文件)

 "r+"(读写) - 为了读和写,打开一个文本文件 - 如果文件不存在(出错)

 "w+"(读写)- 为了读和写,创建一个文本文件 - 如果文件不存在(创建一个新的文件)

 "a+"(读写)- 打开一个文本文件,在文件末尾进行读写 - 如果文件不存在(创建一个新的文件)

 "rb+"(读写)- 为了读和写,打开一个二进制文本文件 - 如果文件不存在(出错)

 "wb+"(读写)- 为了读和写,创建一个二进制文本文件 - 如果文件不存在(创建一个新的文件)

 "ab+"(读写)- 打开一个二进制文本文件,在文件末尾进行读写 - 如果文件不存在(创建一个新的文件)
int main()
{
	// 创建文本指针变量
	FILE* pf;
	//打开文件
	pf = fopen("text.txt", "r");
	//文件操作
	if (pf == NULL)
	{
		//...
		perror("fopen");
		return 1;
	}
	else
	{
		fclose(pf);
		pf = NULL;
	}
	return 0;
}
 文件的顺序读写

 1.顺序读写函数介绍

  函数    功能          适用于

 fgetc - 字符输入函数 - 所有的输入流

 fputc - 字符输出函数 - 所有的输出流

 fgets - 文本行输入函数 - 所有输入流

 fputs - 文本行输入函数 - 所有输入流

 fscnaf - 格式化输入函数 - 所有输入流

 fprintf - 格式化输出函数 - 所有输出流

 fread   -   二进制输入   -   文件

 fwrite   -   二进制输出   -   文件

实验1,打开一个文件并且输入26个字母 

// 实验1,打开一个文件并且输入26个字母

int main()
{
	// 打开并且写一个文件 - "w"
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	int ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

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

打开读取文件text.txt ,并且将它拷贝进text_cpy.txt 

// 打开读取文件text.txt ,并且将它拷贝进text_cpy.txt

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

	FILE* pw = fopen("text_cpy.txt", "w");
	if (pw == NULL)
	{
		perror("fopen text_cpy.txt");
		fclose(pf);
		pf = NULL;
		return 1;
	}

	// 读取并且写入
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		fputc(ch, pw);
	}

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

使用 fputs 和 fgets 函数 

//使用 fputs 和 fgets 函数

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

	// 使用 fputs函数写文件
	// 函数原型
	// int fputs(const char* str, FILE * stream);
	// const char* str 传入读取的字符串的首地址
	// FILE* stream 将读取的内容写入文件中

	char ch[] = "ouyang is cool\n";
	fputs(ch, pf);
	fputs("hello ouyang", pf);

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


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

	// 使用 fgets函数读取文件
	// 函数原型
	// char* fgets(char* str, int num, FILE * stream);
	// char* str 函数将读取到的数据返回char*类型指针的首地址
	// int num  读取的长度
	// FILE* stream 读取文件的地址
	// 如果读取失败会返回NULL

	char ch[20] = { 0 };

	// 单个读取
	/*fgets(ch, 20, pf);
	printf("%s", ch);*/

	// 连续读取
	while (fgets(ch, 20, pf) != NULL)
	{
		printf("%s", ch);
	}
	
	// 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

使用 fprintf函数和 fscanf 函数 

typedef struct stu
{
	char name[20];
	int age;
	char sex[5];
}S;

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

	// 写入
	S s = { "欧阳",20,"男" };
	fprintf(pf, "%s %d %s", s.name, s.age, s.sex);


	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
typedef struct stu
{
	char name[20];
	int age;
	char sex[5];
}S;
int main()
{
	// 打开文件并且写入
	FILE* pf = fopen("fprintf.txt", "r");
	if (pf == NULL)
	{
		perror("fopen fprintf.txt");
		return 1;
	}

	// 读取文件
	S s = {0};
	fscanf(pf, "%s %d %s", s.name, &(s.age), s.sex);

	// 打印在屏幕上观察
	printf("%s %d %s", s.name, s.age, s.sex);

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

有关于流的概念

  • stdin - 标准输入流,获取我们输入的信息。
  • stdout - 标准输出流,输出我们需要打印的信息
  • fgetc, fgets, fputc, fputs, fscanf, fprintf - 适用于所有流
  • fread, fwrite - 适用于文件流
// 使用标准流

int main()
{
	fputc('a', stdout);
	return 0;
}

 使用 fwrite 和 fread 函数

 

int main()
{
	// 以二进制的形式写文件
	FILE* pf = fopen("fwrite.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen fwrite.txt");
		return 1;
	}

	// 写二进制文件

	// fwrite 函数
	// 函数原型:
	// size_t fwrite(const void* ptr, size_t size, size_t count, FILE * stream);
	// const void* ptr - 指向要写入文件的数据
	// size_t size - 指向数据类型的大小
	// siez_t count -指向数据的数量
	// FILE * stream - 写入的文件指针

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

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

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

	// 读取文件
	// fread 函数
	// 函数原型:
	// size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
	// const void* ptr - 指向要读取文件的数据
	// size_t size - 指向数据类型的大小
	// siez_t count -指向数据的数量
	// FILE * stream - 要读取的文件指针
	int arr[5] = { 0 };
	fread(arr, sizeof(arr[0]), 5, pf);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}

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

文件的随机读写 - 适用于二进制文件

 fseek 函数

// 函数原型:
// int fseek ( FILE * stream, long int offset, int origin );

// FILE * stream - 指向FILE*文件对象的指针
// long int offset - 偏移的字节数
// int origin - 参考位置
// 如:
//SEEK_SET	文件开头
//SEEK_CUR	文件指针的当前位置
//SEEK_END	文件末尾*


int main()
{
	// 读写文件
	FILE* pf = fopen("fseek.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen fseek.txt");
		return 1;
	}

	// 读写
	fputs("hello ouyang",pf);
	fseek(pf, 6, SEEK_SET);
	fputs("to ", pf);

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

int main()
{
	// 打开并且读文件
	FILE* pf = fopen("fseek.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen fseek.txt");
		return 1;
	}

	// 读取文件
	char ch[200] = { 0 };
	while (fgets(ch, 50, pf) != NULL)
	{
		printf("%s\n", ch);
	}

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

ftell 函数 

// 函数原型:
// long int ftell ( FILE * stream );

int main()
{
	// 读写文件
	FILE* pf = fopen("fseek.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen fseek.txt");
		return 1;
	}

	// ftell 函数的使用
	fseek(pf, 6, SEEK_SET);
	long size = ftell(pf);
	printf("Size of myfile.txt: %ld bytes.\n", size);

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

 rewind 函数

// 函数原型:
// void rewind ( FILE * stream );

int main()
{

	// 打开文件并且写入
	FILE* pf = fopen("myfile.txt", "w+");
	char buffer[27];
	int n = 0;
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pf); //写入之后的光标在最后
	rewind(pf); // 回调光标
	fread(buffer, 1, 26, pf); // 将文件中的数据读取到字符数组中

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

	// 打印观察
	buffer[26] = '\0'; // 方便输出字符串,将最后一位设置为'\0'
	printf(buffer); // 打印
	return 0;
}

 文件读取结束的判定

 feof 函数
 注意:该函数不可以通过该函数的返回值来直接判断文件的结束

 作用是当文件结束时,判断是读取失败的原因,还是遇到文件结尾结束

⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
• fgetc 判断是否为 EOF 
• fgets 判断返回值是否为 NULL 

int main()
{
	int c = 0; // 注意:int,⾮char,要求处理EOF
	FILE* fp = fopen("test.txt", "r");
	if (fp==NULL) 
	{
		perror("File opening failed");
		return 1;
	}


	//fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF
	while ((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;
}

文件缓冲区

我们在程序中向文件中写入数据不会是有一条写一条,打个比方说:一个学生
问问题不是说问完一个过几分钟又问一个,则会导致老师无法为其他同学解答
问题,操作系统也是如此,操作系统不光是为了写入文件而服务的,所有这个学生
就会将问题攒着,直到一定的数量就可以去问老师,同理我们写入的文件也是如此
而存放这些数据的空间就叫做文件缓冲区

源代码地址:text_2024_3_26 · 6988b68 · 阳区欠/C语言学习路程 - Gitee.com

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

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

相关文章

IDEA MyBatisCodeHelper Pro最新版(持续更新)

目录 0. 你想要的0.1 包下载0.2 使用jh 1. 功能介绍2. 下载安装2.1 在idea中插件市场安装2.2 在jetbrains插件市场下载安装 3. 简单使用3.1 创建一个SpringBoot项目3.2 配置数据库3.3 一键生成实体类、mapper 0. 你想要的 0.1 包下载 测试系统&#xff1a;Windows&#xff08…

el-table 合计行的一直计算的问题。

前端只有打印日志之后&#xff0c;才发现有计算在反复执行&#xff0c;导致浏览器崩溃。并不是每一列都是这个问题&#xff0c;当然输入不同值后&#xff0c;不知为何会触发如此多次。 . 在开发环境&#xff0c;他会触发几百次getSummaries,生产环境直接崩溃 合计行的代码如下…

入围中国大模型 + 知识管理最佳案例 15 强,杭州悦数 x 中国船舶项目收获认可!

近期&#xff0c;由国内知名的数字化研究与服务机构沙丘社区发布的《2024 中国“大模型知识管理”最佳实践案例 15 强》新鲜出炉&#xff0c;杭州悦数科技有限公司助力中国船舶集团有限公司第七〇八研究所打造的行业方案“基于图和多级智能体的动态排障知识问答系统”榜上有名。…

数据结构之二叉树由浅入深(四)

目录 题外话 正题 第一题 第一题思路 第一题代码详解 第二题 第二题思路 第二题代码详解 第三题 第三题思路 第三题代码及详解 第四题 第四题思路 第四题代码及详解 第五题 第五题思路 第五题代码及详解 题外话 本来昨天就想写完这篇文章,怎么样是不是很大胆?…

力扣124---二叉树的最大路径和(DFS,Java)

目录 题目描述&#xff1a; 思路描述&#xff1a; 代码&#xff1a; 题目描述&#xff1a; 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一…

在Arduino IDE中使用文件夹组织源文件和头文件

在Arduino IDE中使用文件夹组织源文件和头文件 如果你是一名Arduino爱好者&#xff0c;你可能会发现随着项目的复杂度增加&#xff0c;代码的管理变得越来越困难。在Arduino IDE中&#xff0c;你可以通过使用文件夹来更好地组织你的源文件和头文件&#xff0c;使得代码更加清晰…

标定系列——预备知识-OpenCV中与标定板处理相关的函数(四)

标定系列——预备知识-OpenCV中与标定板处理相关的函数&#xff08;四&#xff09; 说明记录棋盘格圆网格 说明 记录了OpenCV中与标定板处理相关的函数用法 记录 棋盘格 圆网格

Python 妙用运算符重载——玩出“点”花样来

目录 运算符重载 主角点类 魔法方法 __getitem__ __setitem__ __iter__ __next__ __len__ __neg__ __pos__ __abs__ __bool__ __call__ 重载运算符 比较运算符 相等 不等 ! 大于和小于 >、< 大于等于和小于等于 >、< 位运算符 位与 & 位…

这样使用ChatGPT,效率翻倍不是梦!四大秘诀公开

随着ChatGPT技术的不断革新&#xff0c;它在我们日常工作中扮演着越来越重要的角色。那么&#xff0c;我们该如何利用ChatGPT来解决工作难题呢&#xff1f; Q1&#xff1a;想要迅速获得ChatGPT的帮助&#xff0c;我们应如何提出问题&#xff1f; 以下是几条高效提问的建议&…

关于v114之后的chromedriver及存放路径

使用selenium调用浏览器时&#xff0c;我一直调用谷歌浏览器&#xff0c;可浏览器升级后&#xff0c;就会再次遇到以前遇到过的各种问题&#xff0c;诸如&#xff1a;1、怎么关闭浏览器更新&#xff1b;2、去哪儿下载chromedriver&#xff1b;3、114版本之后的驱动去哪儿下载&a…

我于窗中窥月光,恰如仰头见“链表”(Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记15:PWM输出

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

线程安全(二)--死锁

TOC 一:什么是死锁??? public class Demo1 {public static void main(String[] args) {Object lockernew Object();Thread threadnew Thread(()->{synchronized(locker){synchronized (locker){System.out.println("hello thread");}}});thread.start();} }上…

Facebook Horizon Worlds:打造数字世界的社交乐园

在数字化时代&#xff0c;社交媒体平台已经成为人们日常生活中不可或缺的一部分。而随着科技的不断发展&#xff0c;人们对于社交体验的需求也在不断演变。在这样的背景下&#xff0c;Facebook推出了全新的虚拟现实社交平台——Facebook Horizon Worlds&#xff0c;旨在打造一个…

3D数据格式导出工具HOOPS Publish如何生成高质量3D PDF?

在当今数字化时代&#xff0c;从建筑设计到制造业&#xff0c;从医学领域到电子游戏开发&#xff0c;3D技术已经成为了不可或缺的一部分。在这个进程中&#xff0c;将3D模型导出为3D PDF格式具有重要的意义。同时&#xff0c;HOOPS Publish作为一个领先的解决方案&#xff0c;为…

Android客户端自动化UI自动化airtest从0到1搭建macos+脚本设计demo演示+全网最全最详细保姆级有步骤有图

iOS客户端自动化UI自动化airtest从0到1搭建macosdemo演示-CSDN博客 一、基础环境 1. 安装jdk 选择jdk8 如果下载高版本 可能不匹配会失败 下载.dmg文件 苹果电脑 &#xff5c; macOS &#xff5c; jdk1.8 &#xff5c; 环境变量配置_jdk1.8 mac-CSDN博客 Java Downloads …

08-研发流程设计(上):如何设计Go项目的开发流程?

在Go 项目开发中&#xff0c;我们不仅要完成产品功能的开发&#xff0c;还要确保整个过程是高效的&#xff0c;代码是高质量的。 所以&#xff0c;Go 项目开发一定要设计一个合理的研发流程&#xff0c;来提高开发效率、减少软件维护成本。研发流程会因为项目、团队和开发模式…

Android 自定义坐标曲线图(二)

Android 自定义坐标曲线图_android 自定义曲线图-CSDN博客 继上一篇文章&#xff0c;点击折线图上的点&#xff0c;显示提示信息进行修改&#xff0c;之前通过回调&#xff0c;调用外部方法&#xff0c;使用popupwindow或dialog来显示&#xff0c;但是这种方法对于弹框显示的位…

【No.21】蓝桥杯组合数学|数位排序|加法计数原理|乘法计数原理|排列数|组合数|抽屉原理|小蓝吃糖果|二项式定理|杨辉三角|归并排序(C++)

组合数学 数位排序 【问题描述】 小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。 例如,2022 排在 409 前面, 因为 2022 的数位之和是 6,小于 409 的数位 之和 13。…

Linux 系统快速安装 nginx (新手版)

1、安装所需依赖 yum -y install pcre pcre-devel gcc openssl openssl-devel zlib zlib-devel &#xff08;pcre&#xff1a; 包括 perl 兼容的正则表达式库 openssl&#xff1a; 支持安全传输协议https(和财务有关系的请求会走的协议) 创建运行用户、组 useradd -M -…