1、我们为什么要使用文件?
之前,我们的C语言都是在内存上对数据进行处理,但是我们知道内存有一个属性-掉电易失性。那么,我们不可能在每次电脑重新启动之后,把数据都重新输入一遍,那可太麻烦了。所以,文件就出现了,什么是文件呢?这里我们先简单地认为,磁盘上的文件是文件,而它具有使数据持久化的功能。我们就是为了使数据持久化才使用的磁盘。
2、文件=文件属性+文件内容
3、文件类型:
文件类型有两种,一种是文本文件;一种是二进制文件。
二进制文件就是,数据在内存当中是什么样子的,到了显示器上还是什么样子。
文本文件,内存中的样子和显示器上的样子不一样,显示其上的样子是按照ASCII码转换显示的。
下面用一个例子来说明:
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
int main(){
int a = 10000;
FILE *fp = fopen("test.txt", "wb");
fwrite(&a, 4, 1, fp);
fclose(fp);
fp = NULL;
system("pause");
return 0;
}
这是text.txt在内存当中的样子,是16进制显示的。
这是在记事本中的样子。
我们可以看出来,记事本中是乱码,这就是文本文件的样子,10 27 00 00被按照ASCII翻译了。
那么,我们如何打印10000呢?程序需要改成这样。
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
int main(){
int a = 10000;
FILE *fp = fopen("test.txt", "w");
fprintf(fp,"%d",a);
fclose(fp);
fp = NULL;
system("pause");
return 0;
}
此时,内存当中就保存了5个字节,10000分别被当作了5个char类型的字符,并且31是1的ascii码值,30是0的ascii码值。这时,记事本中就出现了10000。如下图:
4、文件缓冲区
(1)什么是缓冲区?本质是内存里面的一段内存空间(c帮我们维护)。
(2)为什么要有缓冲区?提高io效率。
(3)缓冲区的刷新方式:a.无缓冲b.行缓冲c.全缓冲
(4)缓冲区的刷新时机:
①如果是全缓冲,缓冲区慢进行刷新。
②如果是行缓冲,遇到’\n’就刷新。
③程序推出时,会进行刷新。
④强制刷新时,会进行刷新,强制刷新函数fflush。
(5)一般,往显示器写,缓冲方式叫做行缓冲;往磁盘写,缓冲方式叫做全缓冲。
注:实际操作时,fclose会自动进行强制刷新。
5、文件指针
文件指针就是文件的地址。一般我们可以这样定义一个文件指针:
FILE * fp;//文件指针变量
6、文件的打开关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
ANSIC规定使用fopen函数来打开文件,fclose来关闭文件。
FILE * fopen(const char * filename,const char * mode);//第一个参数是文件名(可以指定路径,也可以不指定);第二个参数是打开方式。
int fclose(FILE * stream);//关闭文件,参数是文件流。
打开方式如下:
r->只读,为了输入数据,打开一个已经存在的文本文件,如果文件不存在就会出错。
w->只写,为了输出数据,打开一个文本文件,如果文件不存在,会建立一个新的文件。
a->,向文本文件尾添加数据,a和w的不同就是a是从末尾接着写;而w则是从头开始写,会覆盖原始数据。
注:在r、w、a之后加b是对二进制文件进行操作,加+号表示读写操作都能进行。
7、文件的顺序读写
有下面几个函数需要介绍:
fgetc、fputc、fgets、fputs,这四个函数都是文本操作,前面两个是对单个字符进行操作分别是字符输入函数、字符输出函数;后面两个是对某一行进行操作,分别是文本行输入函数、文本行输出函数。
fscanf、fprintf,这两个函数是格式化输入函数、格式化输出函数。
fread、fwrite是二进制输入和二进制输出函数,只适用于文件。而前面的六个函数适用于所有的输入流、输出流。
8、文件的随机读写
来介绍三个函数:
(1)fseek
int fseek(FILE * stream,long int offset,int origin);//第一个参数是文件流,第二个参数是偏移量,第三个参数是基准点。
注:偏移量是从基准点开始算起的,基准点可以设置为SEEK_SET、SEEK_CUR、SEEK_END,分别代表的是文件的起始位置、文件指针的当前位置和文件的末尾位置。
(2)ftell
返回文件指针相对于起始位置的偏移量
long int ftell(FILE * stream);
(3)rewind
让文件指针的位置回到文件的起始位置。
void rewind(FILE * stream);
9、文件的结束判定
(1)feof和fread
feof函数,返回值为非零时表示读完。
fread函数,返回成功读取元素的个数。
(2)
注意:在文件读取过程中,不能用feof函数的返回值直接来判断文件是否结束。==因为,读取文件时不仅要考虑结束的问题,也应该想到文件读取出错的问题。==所以,有的时候文件可能不是完整地读取结束了,而是出错了没有读完,这两种情况都要考虑。
a.文本文件读取是否结束,判断标准如下:
●fgetc判断是否为EOF.
●fgets判断返回值是否为NUL.
b.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。