C语言文件操作
目录
- 1.文件指针
- 2.文件的打开和关闭
- 3.文件的读写
- 3.1文件的顺序读写
- fgetc和fputc
- fgets和fputs
- fscanf和fprintf
- fread和fwrite
- 3.2文件的随机读写
- fseek
- ftell
- rewind
- 4.文本文件和二进制文件
- 5.文件读取结束的判定
- 6.文件缓冲区
1.文件指针
在文件操作中,一个关键的概念是文件类型指针,简称文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE
这个FILE
结构体在不同的编译器中的成员内容不完全相同,但大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面创建一个FILE*
的指针变量:
FILE* pf;
2.文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束后需要关闭文件
用fopen函数打开文件
FILE * fopen ( const char * filename, const char * mode );
filename
是要打开文件的文件名mode
是文件的打开方式- 如果打开文件成功,会返回一个
FILE*
的指针变量指向该文件,也相当于建立了指针和文件的关系 - 如果打开失败,会返回一个
NULL
指针,所以在打开一个文件后,需要检查是否打开成功
mode
打开方式如下:
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
“wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
打开一个文件后,还需将这个文件关闭,用到fclose函数
下面我们打开一个文件,并且使用后将其关闭
int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//关闭文件fclose(pf);pf = NULL;//最后要把文件指针赋为空return 0;
}
3.文件的读写
首先我们需要明白什么是输出
,输入
在前面的内容中,我们习惯把printf
叫做输出函数,把scanf
叫做输入函数
其实,所谓的输入输出是对于程序(内存)而言
- 把内存中的数据取出来,让数据在屏幕上显示出来,这就是输出/写,因为把数据从内存中取出来
- 把从键盘获得的数据存到内存中,这就叫输入/读
现在有了文件这个概念,也就是内存与文件中有一种输入输出关系 - 我们将内存中的数据取出,放到文件中,就叫做输出/写
- 将数据的来源从键盘换做文件,从文件中获得数据放到内存中,就叫做输入/读
这里要好好理解输入输出,便于学习下面的读写操作
3.1文件的顺序读写
fgetc和fputc
fputc是字符输出函数,适用于所有输入流
int fputc ( int character, FILE * stream );
character
是要输出的字符,是int
类型的原因是字符以ASCII码的形式存储stream
是指向标识输出流的FILE指针- 如果输出成功,返回所写字符的ASCII值
- 如果输出失败,返回
EOF
下面我们向test.txt
中写几个字符
int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写文件fputc('a', pf);fputc('b', pf);fputc('c', pf);fputc('d', pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
打开
test.txt
文件,可以看见写文件成功
这里注意,因为以
"w"
方式打开文件,所以在每次写入文件都是从头开始写,也就是会覆盖上次写入的内容,如果想接着上次的内容写,就需要以"a"
方式打开文件
fgets是字符输入函数,适用于所有输入流
int fgetc ( FILE * stream );
- 如果读文件成功,会返回读到字符的ASCII值
- 如果失败,返回
EOF
- 在FILE中有一个定位文件读取位置的一个指针,当调用
fgetc
后,这个定位指针会向后挪动,指向下一个字符,所以如果文件中有许多字符,多次调用fgetc
函数即可
下面我们读取test.txt
文件
int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件int ret = fgetc(pf);printf("%c", ret);ret = fgetc(pf);printf("%c", ret);ret = fgetc(pf);printf("%c", ret);ret = fgetc(pf);printf("%c", ret);//关闭文件fclose(pf);pf = NULL;return 0;
}
成功读取
fgets和fputs
fputs是文本行输出函数,适用于所有输入流
int fputs ( const char * str, FILE * stream );
str
是要写入文件的字符串- 如果写入文件成功,返回一个非负值
- 如果失败,返回
EOF
- 每写入一个字符串不会换行,如果想换行就要写入
\n
下面写入2个字符串
int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写入文件fputs("hello!\n", pf);fputs("你好!\n",pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
写入成功:
fgets是文本行输入函数,适用于所有输入流
char * fgets ( char * str, int num, FILE * stream );
- 将读到的字符串放到指针
str
指向的空间中 num
是读取的字符数(包括\0
)- 传参
num
个,其实会读取文件中num-1
个字符,最后一个位置放\0
fgets
只处理一行字符串,如果读的数大于某一行的长度,也不会去读下一行的字符串fgets
每处理一次,FILE中的定位指针会向后挪动,指向下一个位置- 如果函数操作成功,返回
str
- 失败返回NULL
int main()
{//打开文件FILE* pf = fopen("test.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;
}
fscanf和fprintf
fprintf是格式化输出函数 ,适用于所有输入流
int fprintf ( FILE * stream, const char * format, ... );
这个函数我们可以与printf
函数对比,只是参数多了一个FILE
指针,其他都相同
我们可以按照我们自己规定的格式去写入文件
下面我们用一下fprintf
函数:
struct A
{char name[20];int age;float score;
};
int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}struct A a = { "jack",18,100.0 };fprintf(pf, "%s %d %f", a.name, a.age, a.score);//关闭文件fclose(pf);pf = NULL;return 0;
}
test.txt文件:
可以看到,文件中的格式的确是我们规定的格式。
fscanf是格式化输入函数,适用于所有输入流
int fscanf ( FILE * stream, const char * format, ... );
这个函数我们可以与scanf
函数对比,只是参数多了一个FILE
指针
int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}struct A a = {0};fscanf(pf, "%s %d %f", a.name, &(a.age), &(a.score));printf("%s %d %f", a.name, a.age, a.score);//关闭文件fclose(pf);pf = NULL;return 0;
}
成功读取
fread和fwrite
fwrite是二进制输出函数,只适用于文件流
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
- 指针
ptr
是要写入文件内容的地址,因为不确定是什么数据的类型,所以是void*
类型 size
是一个写入的每个元素的大小,单位是字节counrt
是写入元素的个数- 如果写入成功,返回写入元素总数,一般情况下,这个成功的返回值与
count
相等 - 如果返回值与
count
不相等,就说明在写入的过程中有错误 - 如果
size
或count
为0,则返回值为0
int main()
{struct A a = { "jack",18,100.0 };//打开文件FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}//写入文件fwrite(&a, sizeof(struct A), 1, pf);//关闭文件fclose(pf);pf = NULL;return 0;
}
因为是二进制文件,所以在文件中的内容我们看不懂,但是机器可以读懂
fread是二进制输入函数,只适用于文件流
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
- 将读取到的数据
ptr
指向的空间中 size
是读取每个元素的大小,单位是字节counrt
是读取元素的个数- 如果成功,返回值为读取到元素的个数,一般情况下,这个成功的返回值与
count
相等 - 如果返回值与
count
不相等,就说明读取时发生读取错误或到达文件末尾 - 如果
size
或counrt
为零,则该函数返回零,并且流状态和 ptr 指向的内容保持不变
int main()
{struct A a = { 0 };//打开文件FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//读文件fread(&a, sizeof(struct A), 1, pf);printf("%s %d %f", a.name, a.age, a.score);//关闭文件fclose(pf);pf = NULL;return 0;
}
成功读文件
3.2文件的随机读写
fseek
根据文件指针的位置和偏移量来定位文件指针
int fseek ( FILE * stream, long int offset, int origin );
offset
是从origin
偏移的字节数origin
是用作offset
参考的位置
origin
的值:
常量 | 参考位置 |
---|---|
SEEK_SET | 文件开头 |
SEEK_CUR | 文件当前位置 |
SEEK_END | 文件结尾 |
首先我们在文件中存储abcdef
我们先用fgetc
取出三个字符
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 2, SEEK_CUR);ch = fgetc(pf);printf("%c\n", ch);}
由前面知识点可知,每使用一次fgetc函数,那个“定位”指针就会往后挪动位,此时定位指针应该指向字符d
,如果再使用fgetc
就会得到字符d
这时,使用fseek
函数,调整指针位置
fseek(pf, 2, SEEK_CUR);
这句代码的意思是:根据SEEK_CUR
位置,向后挪动2位,这时再调用fgetc就会取出字符f
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fseek(pf, 2, SEEK_CUR);ch = fgetc(pf);printf("%c\n", ch);}
这个函数的参数
offset
也可以是负数,就表示根据orgin
位置向前移动定位指针
ftell
返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
程序中使用了3次fgetc
函数,文件指针向后移动3次,所以再用ftell
返回的偏移量就是3
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);//fseek(pf, 2, SEEK_CUR);int num = ftell(pf);printf("%d\n", num);}
rewind
让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );
程序中使用了3次fgetc
函数,文件指针向后移动3次,再使用rewind
函数将指针回到起始位置,所以再fgetc
就得到第一个字符a
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);//fseek(pf, 2, SEEK_CUR);//int num = ftell(pf);
// ch = fgetc(pf);rewind(pf);ch = fgetc(pf);printf("%c\n", ch);}
4.文本文件和二进制文件
根据数据的类型,数据文件可以分为两种:文本文件和二进制文件
数据在内存中以二进制的形式存储,如果不加转换的存储到文件中,就是二进制文件
如果要求在文件中以ASCII码的形式存储,则需要在存储前爪转换,以ASCII字符的形式存储的文件就是文本文件。
字符一律以ASCII形式存储
数值型数据既可以使用二进制形式,也可以是ASCII码形式存储
下面以10000为例:
10000的二进制:
所以10000的二进制形式存储就是这样
如果把10000以ASCII形式存储,先把10000,看作字符1和四个字符0组成的一个字符串,1的ASCII码值为49,49的二进制为00110001,0的ASCII码值为48,48二进制为00110000
5.文件读取结束的判定
文本文件判断是否读取结束:
1.fgetc
判断返回值是否为EOF
2.fgets
判断返回值是否为NULL
二进制文件判断是否读取结束:
fread
判断返回值是否小于实际要读的个数
C语言stdio.h
还有2个函数判断文件读取结束的原因:
feof函数和ferror函数
- feof,若返回值为真,就说明文件正常读写遇到文件结束标志而结束的
- ferror,若返回值为真,就说明文件在读取过程中出错而结束
判断文本文件读取结束原因的例子:
int main()
{int c = 0;FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}while ((c = fgetc(pf)) != EOF){putchar(c);}if (ferror(pf)){printf("I/O error when reading\n");}else if (feof(pf)){printf("End of file reached successfully\n");}fclose(pf);pf = NULL;return 0;
}
判断二进制文件读取结束原因的例子:
enum
{SIZE = 1
};
int main()
{FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}int ret = 0;int code = 0;code = fread(&ret, sizeof(char),SIZE , pf);if (code == SIZE){printf("Array read successfully\n");}else{if (ferror(pf))printf("Error reading\n");else if(feof(pf)){printf("End of file reached successfully\n");}}
}
6.文件缓冲区
ANSIC 标准采用缓冲文件系统处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块文件缓冲区
从内存向磁盘输出数据会先送到内存中的缓冲区,装
满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓
冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区
以输出(写文件)为例
内存中的数据不是直接就存到文件中的,数据需要先存放到一个叫做输出缓冲区的空间。
想要让输出缓冲区中的数据再存放到文件中有2种情况:
1.缓冲区满了
2.主动刷新缓冲区
想主动刷新缓冲区,要使用fflush
函数
并且fclose函数在关闭文件时,也会刷新缓冲区
所以要记住:
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题。
相关文章:

C语言文件操作
目录1.文件指针2.文件的打开和关闭3.文件的读写3.1文件的顺序读写fgetc和fputcfgets和fputsfscanf和fprintffread和fwrite3.2文件的随机读写fseekftellrewind4.文本文件和二进制文件5.文件读取结束的判定6.文件缓冲区1.文件指针 在文件操作中,一个关键的概念是文件…...

Flink中核心重点总结
目录 1. 算子链 1.1. 一对一(One-to-one, forwarding) 1.2. 重分区(Redistributing) 1.3. 为什么有算子链 2. 物理分区(Physical Partitioning) 2.1. 什么是分区 2.2. 随机分区ÿ…...
gismo中NURBS的相关函数的使用---待完善
文章目录 前言一、B样条的求值1.1 节点向量的生成1.2 基函数的调用1.3 函数里面的T指的是系数类型二、以等几何两个单元12个控制点为例输出的控制点坐标有误1.4二、#pic_center <table><tr><td bgcolor=PowderBlue>二维数2.12.22.32.4三、3.13.23.33.4四、4.…...
5.数据共享与持久化
数据共享与持久化 在容器中管理数据主要有两种方式: 数据卷(Data Volumes)挂载主机目录 (Bind mounts) 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性: 数据…...
RabbitMQ-客户端源码之AMQCommand
AMQCommand不是直接包含Method等成员变量的,而是通过CommandAssembler又做了一次封装。 接下来先看下CommandAssembler类。此类中有这些成员变量: /** Current state, used to decide how to handle each incoming frame. */ private enum CAState {EXP…...

linux设置登录失败处理功能(密码错误次数限制、pam_tally2.so模块)和操作超时退出功能(/etc/profile)
一、登录失败处理功能策略 1、登录失败处理功能策略(服务器终端) (1)编辑系统/etc/pam.d/system-auth 文件,在 auth 字段所在的那一部分添加如下pam_tally2.so模块的策略参数: auth required pam_tally2…...

Centos7上Docker安装
文章目录1.Docker常识2.安装Docker1.卸载旧版本Docker2.安装Docker3.启动Docker4.配置镜像加速前天开学啦~所以可以回来继续卷了哈哈哈,放假在家效率不高,在学校事情也少点(^_−)☆昨天和今天学了学Docker相关的知识,也算是简单了解了下&…...

新瑞鹏“狂飙”,宠物医疗是门好生意吗?
宠物看病比人还贵,正在让不少年轻一族陷入尴尬境地。在知乎上,有个高赞提问叫“你愿意花光积蓄,给宠物治病吗”,这个在老一辈人看来不可思议的魔幻选择,真实地发生在当下的年轻人身上。提问底下,有人表示自…...

Spring循环依赖问题,Spring是如何解决循环依赖的?
文章目录一、什么是循环依赖1、代码实例2、重要信息二、源码分析1、初始化Student对Student中的ClassRoom进行Autowire操作2、Student的自动注入ClassRoom时,又对ClassRoom的初始化3、ClassRoom的初始化,又执行自动注入Student的逻辑4、Student注入Class…...

更改SAP GUI登录界面信息
在SAP GUI的登录界面,左部输入登录信息如客户端、用户名、密码等,右部空余部分可维护一些登录信息文本,如登录的产品、客户端说明及注意事项等,此项操作详见SAP Notes 205487 – Own text on SAPGui logon screen 维护文档使用的…...

分布式微服务架构下网络通信的底层实现原理
在分布式架构中,网络通信是底层基础,没有网络,也就没有所谓的分布式架构。只有通过网络才能使得一大片机器互相协作,共同完成一件事情。 同样,在大规模的系统架构中,应用吞吐量上不去、网络存在通信延迟、我…...

进大厂必备的Java面试八股文大全(2023最新精简易懂版,八股文中的八股文)
为什么同样是跳槽,有些人薪资能翻三倍?” 最近一个粉丝发出了灵魂拷问,类似的问题我收到过很多次,身边也确实有认识的同事、朋友们有非常成功的跳槽经历和收益,先说一个典型例子: 学弟小 A 工作一年半&am…...

都说测试行业饱和了,为什么我们公司给初级测试开到了12K?
故事起因: 最近我有个刚毕业的学生问我说:我感觉现在测试行业已经饱和了,也不是说饱和了,是初级的测试根本就没有公司要,哪怕你不要工资也没公司要你,测试刚学出来,没有任何的项目经验和工作经验…...

解决Idea启动项目失败,提示Error running ‘XXXApplication‘: Command line is too long
IDEA版本为:IntelliJ IDEA 2018.2 (Ultimate Edition)一、问题描述有时当我们使用IDEA,Run/Debug一个SpringBoot项目时,可能会启动失败,并提示以下错误。Error running XXXApplication: Command line is too long. Shorten comman…...

GB/T28181-2022针对H.265、AAC的说明和技术实现
GB/T28181-2022规范说明GB/T28181-2022相对来GB/T28181-2016针对H.265、AAC的更新如下:——更改了“联网系统通信协议结构图”,媒体流通道增加了 H.265、G.722.1、AAC(见 4.3.1,2016 年版的 4.3.1)。——增加了对 H.26…...

开关电源环路稳定性分析(11)——观察法找零极点
大家好,这里是大话硬件。 这篇文章主要是分享如何用观察法直接写出补偿网络中的零极点的表达式。 在前面的文章中,我们分别整理了OTA和OPA型的补偿网络,当时有下面的结论。 针对某个固定的补偿网络,我们可以用数学的方法推导补偿…...

焕新启航,「龙蜥大讲堂」2023 年度招募来了!13 场技术分享先睹为快
龙蜥大讲堂是龙蜥推出的系列技术直播活动,邀请龙蜥社区的开发者们分享围绕龙蜥技术展开,包括但不限于内核、编译器、机密计算、容器、储存等相关技术领域。欢迎社区开发者们积极参与,共享技术盛宴。往期回顾龙蜥社区技术系列直播截至目前已举…...

推广传单制作工具
临近节日如何制作推广活动呢?没有素材制作满减活动宣传单怎么办?小编教你如何使用在线设计工具乔拓云,轻松设计商品的专属满减活动宣传单,不仅设计简单,还能自动生成活动分享链接,只需跟着小编下面的设计步…...
软件设计(十一)数据结构(上)
线性结构 线性表 线性表是n个元素的有限序列,通常记为(a1,a2....an),特点如下。 存在唯一的一个称作“第一个”的元素。存在位移的一个称作“最后一个”的元素。除了表头外,表中的每一个元素均只有唯一的直接前趋除了表尾外&…...

https协议
文章目录对称加密方案非对称加密方案对称加密方案非对称加密方案对称加密方案非对称加密方案数字证书因为HTTP是明文传输,所以会很有可能产生中间人攻击(获取并篡改传输在客户端及服务端的信息并不被人发觉),HTTPS加密应运而生。 …...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...