一、什么是文件
1、文件的概念
对于文件相比大家都不陌生,这里我们给出比较权威一点的定义:
文件是以硬盘为载体存储在计算机上的信息集合
文件系统功能是操作系统的重要功能和组成部分。在Windows操作系统中打开“我的电脑”,或“资源管理器”,可以看到很多文件,每个文件都有自己的文件名和自己的属性。
在操作系统中,文件是指驻留在外部介质(如磁盘等)中的一个有序数据集,可以是源文件、目标程序文件、可执行文件,也可以是待输入的原始数据,或者是一组输出的结果。使用应用程序的时候,通常保存功能实现把数据从内存中写入文件中,这就是所谓的“存盘”,打开功能实现把磁盘文件的内容读取到内存。
就比如我们平时所写的记事本,都是先把数据写入到内存当中去,当保存后,才会把这些数据从内存写入到磁盘文件中。。
2、文件类型
从程序设计的角度来说,一般分为两种:程序文件 和 数据文件 (从文件的不同功能来分类)
程序文件一般有 程序源文件(后缀为.c)
目标文件(windows环境后缀为.obj)
可执行程序(Windows环境为.exe)
数据文件 内容不一定为程序,而是程序运行时所需要的数据
3、文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含 3 部分:文件路径 + 文件名主干 + 文件后缀 (分别对应红色,蓝色和黄色)
例如: c:\code\ test .txt
为了方便起见,文件标识常被称为 文件名 。
4、文本文件和二进制文件
在c语言中,根据数据存储的编码形式,数据文件可以分为文本文件和二进制文件两种。
文本文件是以字符ASCLL码值进行存储与编码的文件,其文件内容就是字符。那么二进制自然就是存储二进制文件。从文件的逻辑结构上讲,c语言把文件看作是数据流,也就是后面讲的
FILE* stream,并将数据按顺序以一维方式组织存储。
5、缓冲文件系统
由于系统对磁盘文件数据的存取速度与内存数据存取访问速度不同,而文件数据量较大,数据从磁盘读取到内存或从内存写到磁盘不可能瞬间完成,所以为了提高效率,c程序对文件的处理采用缓冲文件系统的方式进行,程序与文件的数据交换通过文件缓冲区来完成。
二、为什么要使用文件
想必我们都学过结构体,在写结构体的时候我们应该都写过用于存储数据的线性表——链表,就比如说我们再熟悉不过的通讯录。但是我们在使用的时候可能会发问,不是说链表是用来存储数据的吗,为什么当我输入数据后,退出程序的时候数据又都不存在了,等到下次再运行的时候又要重新输入?
这就要谈到文件的重要性了,我们之前所写入程序的数据都是存放在内存当中,当程序退出的时候,内存当中的数据自然就全部销毁了。如果我们能把输入到程序里面的数据给存起来,等到下次用的时候再加载到程序当中,这就做到了数据的持久化,上面的问题也就迎刃而解。
我们使用文件,将数据直接存放到文件当中,然后下次要用的时候只需要重新加载就可以了
三、文件打开和关闭
1、文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。为了专门识别这种结构体变量,该结构体类型将会被系统声明,取名FILE .
以vs2013集成编译环境为例,它里面提供的stdio.h头文件有如下文件类型申明:
struct _iobuf {
char * _ptr ;
int _cnt ;
char * _base ;
int _flag ;
int _file ;
int _charbuf ;
int _bufsiz ;
char * _tmpfname ;
};
typedef struct _iobuf FILE ;
(注意:对于不同的c编译器的FILE类型所包含的内容不完全相同,但是大同小异)
每当打开一个文件的时候,系统会根据文件的情况自动创建一个 FILE 结构的变量,并填充其中的信息,使用者不必关心细节。 一般都是通过一个FILE 的指针来维护这个 FILE 结构的变量,这样使用起来更加方便。
下面我们可以创建一个 FILE* 的指针变量 :
FILE * pf ; // 文件指针变量
这个pf指向某个文件的信息区(一个结构体变量),然后通过这个信息区来访问这个文件。
2、文件的打开和关闭
前面所说到,知道了文件的信息区就可以访问文件,那么在访问之前应该先打开文件,当不再使用文件的时候就应该关闭文件。
对应打开文件,ANSIC规定使用fopen函数来打开文件:其定义如下
FILE * fopen ( const char * filename , const char * mode );
返回类型为FILE*
filename为文件名,类型为char*
mode为操作方式,类型为char*
如果fopen打印失败则会返回空指针
对应关闭文件,其定义如下
int fclose ( FILE * stream );
返回类型为int类型
stream为文件流,后面会讲到
操作方式(mode)具体有如下:
mode
文件操作方式 | 含义 | 指定文件不存在 |
"r"(只读) | 为输入数据,打开一个已经存在的文件 | 直接报错 |
"w"(只写) | 为输入数据,打开一个已经存在的文本文件 | 建立一个新的文本文件 |
"a"(追加) | 像文本文件尾添加数据 | 建立一个新文件 |
"rb"(只读) | 为了输入数据,打开一个二进制文件 | 直接报错 |
"wb"(只写) | 为输出数据,打开一个二进制文件 | 建立一个新的文件 |
"ab"(追加) | 向一个二进制文件尾添加数据 | 出错 |
"r+"(读写) | 为了读和写,打开一个文本文件 | 出错 |
"w+"(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
"a+"(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
"rb+"(读写) | 为了读写,打开一个二进制文件 | 报错 |
"wb+"(读写) | 为了读写,建立一个新的二进制文件 | 建立一个新的文件 |
代码举例:
#include<stdio.h> #include<stdlib.h> int main() { FILE* pf = fopen("ilike.txt", "w"); if (pf == NULL) printf("pf fopen \"ilike\" fail"); else { fputs("abcdefg", pf); fclost(pf); pf=NULL } return 0; }
我们首先看到我们工程文件的目录里面:显示时不存在ilike.txt这个文件
当我们运行代码后,里面出现了ilike.txt这个文件:
打开ilikex.txt这个文件显示正如我们代码所输入的那样:
c语言:文件处理操作-2