【文件】C语言文件操作及其使用总结篇【初学者保姆级别福利】
【文件】C语言文件操作及其使用总结篇【初学者保姆级别福利】
一篇博客学好动态内存的管理和使用
这篇博客干货满满,建议收藏再看哦!!
求个赞求个赞求个赞求个赞 谢谢
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
本篇基本上涵盖了初学阶段动态内存的所有知识点,喜欢的伙伴一定要看完哦!
强烈建议本篇收藏后食用~ 干货满满!
看完这篇博客,相信伙伴们可以基本上掌握以下内容:
1.为什么使用文件
2.什么是文件
3.文件的打开和关闭
4.文件的顺序读写
5.文件的随机读写
6.文件读取结束的判定
7.文件缓冲区
文章目录
前言
1.为什么要使用文件
在以前的C语言学习当中,我们了解到,我们在运行程序的时候所定义的数据,是保存在内存中的,有可能是栈区上,有可能是堆区上,也有可能是在其它地方上,但是,这些地方,都是属于内存上的。在内存上的数据,是计算机在程序运行的时候所开辟出来的,因此,在程序结束的时候,内存上的空间都会被返还给内存,因此我们是做不到数据的持久化保存的。
这时,我们就需要用到文件。使用文件,我们就可以将数据直接存放在电脑的硬盘上,做到了数据持久化。
什么是文件?
磁盘上的文件是文件。但是在程序设计中,我们一般所指的文件有两种:程序文件、数据文件。
关于这部分知识相对于没有那么的重要,博主在这里就不展开细讲,想了解的小伙伴可以给我私信留言哦。
文件的打开和关闭
文件指针
首先,我们要知道,每一个被使用的文件都在内存中开辟了一个相应的文件信息去,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是要保存在一个结构体当中的。但是这个结构体是不用我们自己声明的,系统已经帮我们声明好了,已经被取好名了,为
FILE。
另外,每次我们打开文件的时候,系统都会自己生成一个FILE结构的变量,里面有关信息系统会自己录入,我们作为使用者暂时不必关心细节。
OK。接下来,我们想要找到这个系统给我们准备好的结构体并使用它,我们就要通过文件指针找到这个文件。
FILE*pf;//文件指针变量
文件的打开和关闭
有了pf这个指针,我们在操作文件之前,就要通过pf来打开文件,在使用结束后一定要记得关闭文件。
想要打开和关闭文件,我们要用到两个函数:
fopen()和fclose()
我们先来看这两个函数的原型:
int main()
{
//打开文件
FILE* fopen(const char* filename, const char* mode);
//关闭文件
int fclose(FILE * stream);
return 0;
}
在fopen()函数中,filename指的是文件名,这个很好理解,fclose()函数中stream指的是,流。关于流的概念,我会在后面继续讲解,这里指的就是我们用FILE*类型定义的函数指针。
而mode,指的是文件的打开方式,为char*类型。
文件的打开方式有如下几种
| 文件使用方式 | 含义 | 如果指定文件不存在 |
|---|---|---|
| “r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | err |
| “w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
| “a”(追加) | 往文本文件尾添加数据 | 建立一个新的文件 |
| “rb”(只读) | 为了输入数据,打开一个二进制文件 | err |
| “wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
| “ab”(追加) | 向一个二进制文件尾添加数据 | err |
| “r+”(读写) | 为了读和写,打开一个新的文件 | err |
| “w+”(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
| “a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
| “rb+”(读写) | 为了读和写打开一个二进制文件 | err |
| “wb+”(读写) | 为了读和写,创建一个新的二进制文件 | 建立一个新的文件 |
| “ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
例子:
int main()
{
FILE*pf1=fopen("test.dat", "w");//这种是相对路径,是要放到程序那个指定文件夹里面才能被找到
FILE* pf2 = fopen("D:\\test.dat", "r");//有位置的叫绝对路径,是可以找到的
//注意\如果只有一个,是会被理解成转义字符的
//所以\都要变成两个
if (pf1 == NULL)
{
perror("fopen");
return 1;
}
//写文件
//关闭文件
fclose(pf1);
pf1 = NULL;
return 0;
}
在这里,我想给各位小伙伴讲一下使用使用文件的一些好习惯和细节:问下大家有注意到fopen()后面这一段代码吗
if (pf1 == NULL) { perror("fopen"); return 1; }
这一段代码的作用,就是防止文件打开失败,而fopen()在文件打开失败的时候,是会返回空指针的,如果我们不加以检验就对pf进行使用,注意:此时pf是个空指针,是会出问题的,所以,我们需要给pf验空。
另外,在我们fclose()关闭文件之后,必须要将pf置为空指针,防止后面对pf进行非法的解引用操作。
文件的顺序读写
基本函数的介绍
文件的顺序读写,我们必须知道一些必要的文件操作函数
| 功能 | 函数名 | 适用于 |
|---|---|---|
| 字符输入函数 | fgetc | 所有输入流 |
| 字符输出函数 | fputc | 所有输出流 |
| 文本行输入函数 | fgets | 所有输入流 |
| 文本行输出函数 | fputs | 所有输出流 |
| 格式化输入函数 | fscanf | 所有输入流 |
| 格式化输出函数 | fprintf | 所有输出流 |
| 二进制输入 | fread | 文件 |
| 二进制输出 | fwrite | 文件 |
例子
int main()
{
FILE* pf = fopen("test.dat", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
fputc('b', pf);//往pf所指向的文件里面写入一个b
fputc('i', pf);
fputc('t', pf);
//按顺序写的
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
我们打开后台文件夹,就可以找到test.txt这个文件了,我们可以看到bit是按照顺序录入进了这个文件当中。

流的概念
流是一个高度抽象的概念
程序-屏幕/硬盘/优盘/光盘…
各种硬件读写方式也不同
为了让写程序的人不用那么麻烦
所以在程序和硬件之间加一个流的概念
C程序只要运行起来,就默认打开了三个流
stdin-标准输入流-键盘
stdout-标准输出流-屏幕
stderr-标准错误流-屏幕
以上三个流都是FILE*类型的
因此我们可以得出,文件是一种流,屏幕,键盘也都是流,而流一般用stream表示。
例子:
//想用fputc给屏幕打印数据
int main()
{
fputc('b', stdout);
fputc('i', stdout);
fputc('t', stdout);
return 0;
//屏幕也是个流,文件也是个流
//我们写数据可以往文件里面写,当然也可以向屏幕上写
}

一些文件操作函数使用的例子
例子1:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
}
//读文件
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);
ret = fgetc(pf);
printf("%c", ret);
ret = fgetc(pf);
printf("%c", ret);
ret = fgetc(pf);
printf("%c", ret);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
分析:
这里的文件是用
"r",也就是读取的方式打开的,我们通过fgetc()函数一次读取一个文件里面的字符,并存进ret后打印。因此,如果我们一开始要现在指定的文件夹里面先写入一些字符,我们F5运行起来之后,我们就可以看到这些打印的字符了。
> 运行后:
例子2:
//读键盘
//从标准输入流里面读取信息
int main()
{
int ret = fgetc(stdin);//从标准输入流读取信息
printf("%c", ret);
ret = fgetc(stdin);
printf("%c", ret);
ret = fgetc(stdin);
printf("%c", ret);
return 0;
}
分析:
从标准输入流(键盘)里面输入信息之后,用printf()打印出来。

例子3:
int main()
{
FILE* pf = fopen("test.dat", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件-按照行来写
fputs("abc\n",pf);
fputs("qwertyuiop", pf);
//这种都叫以文本的形式写进去
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
经过上面的学习,这些代码都比较好理解,这里就不赘述了。
运行之后:

例子4:
int main()
{
FILE* pf = fopen("test.dat", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[10] = { 0 };
fgets(arr, 4, pf);
printf("%s", arr);
fgets(arr, 4, pf);
printf("%s", arr);
//这里的4,事实上其实只会读三个,因为要留位置给\0
//后面接着读是不会从第二行开始读的,要把内容读完才行
return 0;
}
注意:
arr表示从文件录入的数据存入arr中,4表示录入4个字符,pf指向那个文件
但是,此时的录入的4个字符,只有3个是有效的,因为要留位置给'\0'。
后面接着读是不会从第二行开始读的,要把内容读完才行
运行:


fprintf、fscanf、sprintf和sscanf函数的使用
fprintf()函数和fscanf()函数
fprintf()原型:
int fprintf ( FILE * stream, const char * format, ... );
fscanf()原型:int fscanf ( FILE * stream, const char * format, ... );
通过对比我们发现,这两个函数分别比printf,scanf只多了一个参数FILE*stream,这个参数,也就是一个流。
那么我们通过两个例子,就可以很好的理解这两个函数。
例子1:
struct S
{
char arr[10];
int num;
float sc;
};
int main()
{
struct S s = { "abcdef",10,5.5f };
//现在想把它放到文件里面
//对格式化的数据进行写文件
FILE* pf = fopen("test.dat", "w");
if (NULL == pf)
{
perror("fopen");
return 1;
}
//写文件
fprintf(pf, "%s %d %f", s.arr, s.num, s.sc);
fclose(pf);
pf=NULL;
很容易理解,我们想要进行格式化输出的时候,只需要在fprintf()的第一个参数上传我们要操作的流,后面的参数和printf()的使用完全一致。同理,我们也可以很好的理解fscanf()这个函数。
例子2:
现在我们想要把刚才放进test.dat里面的数据还原到一个结构体中来。
struct S
{
char arr[10];
int num;
float sc;
};
//能否读出来,还原成一个结构体?
int main()
{
struct S s = { 0 };
//现在想把它放到文件里面
//对格式化的数据进行写文件
FILE* pf = fopen("test.dat", "r");
if (NULL == pf)
{
perror("fopen");
return 1;
}
//读文件
fscanf(pf,"%s %d %f", s.arr, &(s.num), &(s.sc));
//打印以下看看结果
printf("%s %d %f\n", s.arr, s.num, s.sc);
fclose(pf);
pf = NULL;
return 0;
}
思考:
通过以上两个例子,我们就可以很好的明白fprintf(),fscanf()这两个函数的使用。此时,我们要思考:我们前面说了,键盘,屏幕也都是流,那么,我们将fprint(),fscanf()的第一个参数改成标准的输出输入流,那么它们的作用,就是相当于printf()和scanf()啊。
事实确实是如此:
fprintf(stdout,...,...)和printf(...,...)等价。
fscanf(stdin,...,...)和scanf(...,...)等价。
sprintf()函数和sscanf()函数
其实这两个函数的运用并不属于文件这一部分的内容,但是我们讲到fprintf(),fscanf(),printf,scanf()这些函数,那我们也把这最后两个名字相似的函数讲了,给伙伴们区分一下。
scanf()针对标准输入的格式化的输入语句-stdin
fscanf()针对所有输入流的格式化的输入语句
sscanf()从一个字符串中读取一个格式化的数据
printf()针对标准输出的格式化输出语句-stdout
fprintf()针对所有输出流的格式化输出语句
sprintf()把格式化的数据,转成字符串
例子:
//sprintf/sscanf
//把格式化的数据写到一个字符串里面
struct S
{
char arr[10];
int age;
float f;
};
int main()
{
struct S s = { "hello",20,5.5f };
//能否转化为一个字符串呢
char buf[100] = { 0 };
sprintf(buf, "%s %d %f", s.arr, s.age, s.f);
printf("%s\n", buf);
//能否从buf字符串中还原出一个结构体
struct S tmp = { 0 };
sscanf(buf, "%s %d %f", tmp.arr, &(tmp.age), &(tmp.f));
printf("%s %d %f\n", tmp.arr, tmp.age, tmp.f);
//两次printf的结果应该是一样的
return 0;
}
文件的二进制读写
两个函数:fwrite()函数和fread()函数
fwrite():
原型:size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
第一个参数表示被写数据(可以是个数组)的地址,第二个参数表示每一个数据的大小(如果是数组,就是每个元素的大小),第三个参数表示数据个数(如果不是数组,就是1,如果是数组,就是数组元素个数,第四个参数表示流。
fread():
原型:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
参数含义和fwrite()相同。
顾名思义就是用二进制的形式读写,是我们看不懂的,我们通过两个例子就可以很好的理解这两个函数。
例子:
//二进制的读写
struct S
{
char arr[10];
int num;
float sc;
};
//fwrite
//size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
int main()
{
struct S s = { "abcde",10,5.5f };
//二进制的形式写
FILE* pf = fopen("test.dat", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
fwrite(&s,sizeof(s),1,pf);
//后台打开文件,我们是看不懂的,因为是二进制形式搞进去的
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}

我们是看不懂后台输入文件的含义的,因为我们是以二进制的形式输入的,要想读懂,我们必须通过fread()函数,以二进制的形式读。
//我们要用fread才能看懂
//fread
struct S
{
char arr[10];
int num;
float sc;
};
//fread
//size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
int main()
{
struct S s = {0};
//二进制的形式读
FILE* pf = fopen("test.dat", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读
//参数和fwrite一样
fread(&s, sizeof(struct S), 1, pf);
//都出来之后我们打印出来看看
printf("%s %d %f\n", s.arr, s.num, s.sc);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}

通过fread(),我们就成功读出fwrite()刚刚写进去的内容了。
文件的随机读写
想要掌握文件的随机读写,我们必须掌握的其中一个函数就是fseek()函数
fseek():
这个函数的作用就是用来调整文件指针位置的。
比如说,后台的test.dat里面有一串字符串abcdefg,但是我读的时候不想从头开始读,那么我们就可以通过fseek()函数来调整文件指针的位置,让它从a的位置挪开。
原型:int fseek ( FILE * stream, long int offset, int origin );
第一个参数表示针对的流,第二个参数表示调整后的文件指针相对于原始位置的偏移量,第三个参数表示文件指针的原始位置。
在此其中,第三个参数中我们常用的三个量为:
SEEK_CUR;//current position of file pointer指针当前位置
SEEK_END;//end of file文件末尾
SEEK_SET;//beginning of file文件开头
ftell():
这个函数返回一个整型,告诉我们当前文件指针相对于起始位置的偏移量。
rewind():
这个函数可以让文件指针回到起始位置
那么上面这些函数怎么用呢,我们看一个例子就明白了
例子:
int main() {
FILE* pf = fopen("test.txt", "r");
if (pf == NULL) {
perror("fopen");
}
char ch = 0;
//先打开后台在里面写入abcdefg
//现在里面已经有abcdefg了
ch=fgetc(pf);
printf("%c\n", ch);//此处打印的是a
//现在a已经读完了,文件指针指向的是b,那么怎么跳过b,c直接读d呢?
fseek(pf, 2, SEEK_CUR);//用fseek()调整一下指针位置,跳过两个字符
ch = fgetc(pf);
printf("%c\n", ch);//此处打印的是d
int ret = ftell(pf);
printf("%d\n", ret);//此处打印的是4
rewind(pf);
ret = ftell(pf);
printf("%d\n", ret);//此处打印的是0,因为pf已经被rewind了
fclose(pf);
return 0;
}
文件读取结束的判定
文件读取结束的判定
被错误使用的feof:在很多文章中和教学中经常说feof可以判断结束,其实是不准确的
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件是否结束
feof的作用是用于文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束,如果feof返回值为真,表示正常读取结束;如果为假表示文件读取失败而结束读取。
文本文件读取是否结束,是通过fgetc函数的返回值是否是EOF来判定的
fgets函数正常读取结束的时候会返回空指针,正常读取的时候,返回放字符串的空间起始地址
fread函数在读取的时候,返回的是实际读取到的完整元素的个数
如果发现读取到的完整的元素的个数小于指定的元素个数,这就是最后一次读取了。
例子:
写一个函数拷贝一个文件:
//写代码把test.txt文件拷贝一份,生成test2.txt文件
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL)
{
return 1;
}
FILE* pfwrite = fopen("test2.txt", "w");
if (pfwrite == NULL)
{
fclose(pfread);
pfread = NULL;
return 1;
}
//读写文件
int ch = 0;
while ((ch = fgetc(pfread) != EOF))
{
//写文件
fputc(ch, pfwrite);
}
//判断读取是因为什么结束的
if (feof(pfread))
{
printf("遇到文件结束标志,文件正常结束\n");
}
else if (ferror(pfread))
{
printf("文件读取失败结束\n");
}
//关闭文件
fclose(pfread);
pfread = NULL;
fclose(pfwrite);
pfwrite = NULL;
return 0;
}
文件缓冲区
文件缓冲区
程序数据区(内存)<>硬盘
在这其间存在输出缓冲区和输入缓冲区
例子:
这个例子不是本章重点,只是让伙伴们理解一下文件缓冲区的概念,小伙伴可以复制代码按照指示运行一下就可以理解了,这里不再赘述。
#include<windows.h>
int main()
{
FILE* pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10s-已经在写数据了,打开test.txt文件,发现文件没有内容\n");
Sleep(10000);
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(硬盘)
//注:fflush在高版本vs上不能使用了
printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭文件的时候,也会刷新缓冲区
pf = NULL;
return 0;
}
尾声
能看到这里的小伙伴,如果你已经完全理解了这篇博客的内容,相信你对文件的理解已经提高了一个层次了。如果感觉这篇博客对你有帮助的话,别忘了你的赞,收藏和关注哦
【文件】C语言文件操作及其使用总结篇【初学者保姆级别福利】的更多相关文章
- c语言文件读写操作总结
C语言文件读写操作总结 C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程 ...
- go语言文件操作,这期资料比较详细( 欢迎加入go语言群: 218160862 )
go语言文件操作,这期资料比较详细 欢迎加入go语言群: go语言深圳群 golang深圳 218160862 点击加入 文件操作 func Open(name string) (file *File ...
- C语言文件操作
C语言文件操作,以下以基本的例子和说明来展开怎么通过C语言来进行文件操作. 操作文件,我们得需要知道什么?当然是路径和文件名. 首先我需要知道我操作的文件在哪里,叫什么名字.在C语言中还存在一个打开方 ...
- C语言文件操作相关函数
在实际应用中,我们往往需要对文件进行操作,下面我将介绍C语言的一些关于操作文件的函数. 一.计算机文件 计算机文件是以计算机硬盘为载体存储在计算机上的信息集合,是存储在某种长期储存设备上的一段数据流. ...
- C 语言文件操作
C 语言文件操作 1. 数据流: 程序与数据的交互以流的形式进行.fopen 即打开数据流,fclose 即刷新数据流. 所谓数据流,是一种抽象,表示这段数据像流一样,需要逐步接收,不 ...
- C语言文件操作函数
C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * str ...
- C语言库函数--操作文件
//C库函数读取文件的代码 I/O缓冲机制 C语言库函数写文件都是写在内存中,然后一次写入磁盘.提高了效率. 读写文件,不对系统进行操作,一般采用C语言库函数.移植可以在任何可以对C支持的操作系统,而 ...
- C语言文件操作解析(五)之EOF解析(转载)
C语言文件操作解析(五)之EOF解析 在C语言中,有个符号大家都应该很熟悉,那就是EOF(End of File),即文件结束符.但是很多时候对这个理解并不是很清楚,导致在写代码的时候经常出错,特 ...
- 【转】C语言文件操作解析(三)
原文网址:http://www.cnblogs.com/dolphin0520/archive/2011/10/07/2200454.html C语言文件操作解析(三) 在前面已经讨论了文件打开操作, ...
- 关于C语言文件操作
关于C语言的文件操作之前我也写过一篇博客来介绍,但是当时写的很不全面,只是简单的使用了一下 ,今天再从新学习一下. 1.文件的写 首先还是先看一个简单的例子: include<stdio.h&g ...
随机推荐
- Educational Codeforces Round 80 A - D题题解(又是卡很久的一场比赛)
第八场 CodeForces - 1288A. Deadline Example input 3 1 1 4 5 5 11 output YES YES NO Note In the first te ...
- vivo 全球商城:订单中心架构设计与实践
一.背景 随着用户量级的快速增长,vivo 官方商城 v1.0 的单体架构逐渐暴露出弊端:模块愈发臃肿.开发效率低下.性能出现瓶颈.系统维护困难. 从2017年开始启动的 v2.0 架构升级,基于业务 ...
- 《3D编程模式》写书-第5次记录
大家好,这段时间我完成了对初稿的第一轮修改,即将开始第二轮的修改 这里是所有的的写书记录: <3D编程模式>写书记录 本轮修改主要进行了下面的修改: 修改错误 修改了UML错误.文字错误. ...
- C#格式化输入数据为货币格式
private void btn_Get_Click(object sender, EventArgs e) { double P_dbl_value;//定义double类型变量 if (doubl ...
- 同步FIFO设计
FIFO有一个读口和一个写口,读写时钟一致是同步FIFO,时钟不一致就是异步FIFO IP设计中通常使用的是同步FIFO 异步FIFO通常使用在跨时钟域设计中 RAM(Random Access Me ...
- UPF - Power Intent Basic
Mainstream Low Power techniques Low Vth - 阈值电压比较低,翻转时间小,漏电流比较大,功耗大,速度快 High Vth - 阈值电压比较高,翻转时间长,漏电流比 ...
- [转帖]十分钟掌握 Vim 编辑器核心功能
https://juejin.cn/post/6929248764746006535 前言 相信不论是前端还是后台多多少少都需要上到服务器上做一些操作,改改配置文件等,大多数 Linux 服务器默认都 ...
- [转帖]JVM 输出 GC 日志导致 JVM 卡住,我 TM 人傻了
https://www.jianshu.com/p/51380e04eab1 最近,我们升级了 Java 17.后来,我们的 k8s 运维团队为了优化我们的应用日志采集, 将我们所有 pod (你可以 ...
- [转帖]MegaCli命令
MegaCli命令 设置jbod模式 1.3 LSI 9260/9261 raid卡配置 LSI 9260/9261 raid卡支持0.1.10.5.6.50.60 常用命令: 清除raid卡原有的配 ...
- 申威3231服务器Redis性能验证-及最全信创CPU性能分析
申威3231服务器Redis性能验证-及最全信创CPU性能分析 背景 公司里面新进了几台服务器. 有台申威服务器. 因为前段时间参与过一次申威的POC验证. 当时对性能有一点简单的理解. 但是因为不方 ...

