前言: 我们应该知道一般程序运行时产生的数据是存放在内存中的。但是如果程序关闭后这些内存就会被系统回收,如果内存内的有用的数据没有被保存下来,这些数据就丢失了。所以这个时候我们就可以使用磁盘来储存我们的数据。
目录
程序文件的分类
文件名
二进制文件和文本文件
文件的打开和关闭
流的概念:
标准流:
文件打开和关闭
文件的顺序读写函数:
fseek
ftell
rewind
文件读取结束的判定
文件缓冲区的概念
程序文件的分类
程序文件一般分为两类:程序文件和数据文件。
程序文件: 源代码(.c文件) 、目标文件(.obj) 、 可执行程序(.exe)
数据文件:用于保存数据的文件。 区别于用来运行程序的程序文件。
文件名
每个文件都有一个路径和名称, 这是用来寻找该文件的途径。 便于用户使用。
文件名一般包含三个部分: 文件路径, 文件主干, 文件后缀
二进制文件和文本文件
一个数据,我们都知道数据在计算机中是以二进制的方式进行储存, 如果这个数据从计算机中不加转换的就输出到外存的文件中, 就是二进制文件。
但是如果这个数据转换成ASCII码的形式, 那么就是文本文件。
字符一律通过ASCII码的形式进行储存, 数值则ASCII和二进制储存皆可。
比如10000这个数值, 如果用ASCII就花费五个字节, 但是用二进制就只需要4个字节。
文件的打开和关闭
流的概念:
程序数据进行输出到外部设备时, 以及程序的数据从外部设备获取数据时, 不同的外部设备的输入输出操作是各不相同的。 为了方便对各种设备进行方便的操作呢, 人们抽象出了流的概念。 可以将其抽象成一条充满字符的河。
我们通过向这条河中写数据, 或者从这条河中拿数据, 这就是数据的输入和输出。
标准流:
我们打开一个程序, 那么我们就默认打开了三个流
一个是标准输入流stdin:标准输⼊流,scanf就是从标准输入流读取数据。
一个是标准输出流stdout: 标准输出流, printf就是将数据输出到标准输出流中。
一个是标准错误流stderr:用于输出错误信息。
三个流的类型是FILE*, 通常称为文件指针。
文件打开和关闭
在文件读写之前应该打开文件,在文件读写之后应该关闭文件。
在我们打开文件之后, 都会返回一个FILE*类型的指针指向该文件, 就建立了文件和指针之间的练习。
打开文件函数:
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+”(读写) 打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写 建⽴⼀个新的⽂件
文件的顺序读写函数:
fgetc() 字符输入函数 所有输入流
fputs() 字符输出函数 所有输出流
fgets() 字符串输入函数 所有输入流
fputs() 字符串输出函数 所有输出流
fscanf() 格式化输入函数 所有输入流
fprintf() 格式化输出函数 所有输出流
fread() 二进制输入函数 文件
fwrite() 二进制输出函数 文件
上述得所有所有输入流包括标准输入流和其他输入流(如文件输入流), 上述的所有输出流包括标准输出流和其他输出流(如文件输出流)。
fseek
int fseek (FILE* stream, long int offset, int origin);
fseek是根据流的初始位置和偏移量来定位一个文件指针位置。
以下为实例:
int main()
{
FILE* Open = fopen("text", "wb");
fputs("hello world", Open);
fseek(Open, 5, SEEK_SET);
fputs("earth", Open);
fclose(Open);
return 0;
}
ftell
long int ftell ( FILE * stream );
返回文件指针相对于起始位置的偏移量.
下图为实例:
int main()
{
FILE* Open;
long size;
Open = fopen("text", "rb");
if(Open == NULL)
{
exit(-1 );
}
fseek(Open, 0, SEEK_END);
size = ftell(Open);
fclose(Open);
printf("%d", size);
}
rewind
void rewind (FILE* stream);
让文件指针的位置返回到起始位置。
以下为实例:
int main()
{
FILE* Open = fopen("text", "w+");
char arr[27];
for(int n = 'A'; n <= 'Z'; n++)
{
fputc(n, Open);
}
rewind(Open);
fread(arr, 1, 26, Open);
fclose(Open);
arr[26] = '\0';
puts(arr);
return 0;
}
文件读取结束的判定
应该要牢记, 判断文件是否读取结束不要直接使用feof。
feof的作用是:当文件读取结束的时候, 判断文件读取结束的原因是不是文件到了末尾。
当读取文本文件时, 判断返回值:EOF(fgetc)或者NULL(fgets)。
当读取二进制文件时, 判断返回值是否小于实际要读取的个数。
文件缓冲区的概念
ANSIC标准采用缓冲文件系统处理数据文件的。缓冲文件系统就是指,系统自动的在内存中为程序中的每一个正在使用的文件开辟一块”文件缓冲区”,从内存向磁盘输入数据应该先通过文件缓冲区, 等到文件缓冲区满了再一起送到磁盘上。如果是磁盘向计算机读入数据,则从磁盘文件中读取数据到文件缓冲区, 然后等到满了再一起读到计算机内存中。
int main()
{
FILE*pf = fopen("text", "w");
fputs("abcdef", pf);
printf("正在写数据,这时候我们可以打开⽂件,因为要观看是否写上内容,因为有10秒缓冲。但是我们发现⽂件没有内容。\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//这个时候其实写上了。
printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
Sleep(10000);
fclose(pf);//刷新缓冲区
pf = NULL;
return 0;
}
因为有缓冲区的存在, c语言操作文件的时候, 需要做刷新缓冲区或者再文件操作结束的时候关闭文件。 否则可能导致读写文件的问题。