萌新的学习笔记,写错了恳请斧正。
目录
每个文件都有一个唯一的文件标识,也就是文件名
文件名包含3个部分:文件路径+文件名主干+文件后缀(可省略)
例如:C:\Windows\WindowsUpdate.log
我们常说的“文件名”是指文件名主干
文件分为程序文件和数据文件
其中数据文件根据数据的组织形式分为文本文件和二进制文件
文本文件以ASCII字符的形式存储,二进制文件就是以二进制存储
程序往往需要输出到各种外部设备,也需要从外部设备获取数据。为了方便程序员对各种不同设备进行输入输出的调控,就抽象出了流的概念。流可以大概理解为数据传递的一个过程
一般情况下,程序想要输入或输出数据都要先打开对应设备的流,然后在操作
那么为什么我们从键盘上输入数据,向控制台(屏幕)上输出数据时,不需要打开流呢?
这就是因为C语言程序启动时就会默认打开3个流,我们称之为标准流
这三个流默认打开,其类型为FILE*,通常也称为文件指针
(为什么流会有类型呢?这就是下面要讲的重点了)
在C语言中,我们通过文件指针来维护各种流的操作
ANSIC标准采用“缓冲文件系统”来处理各种数据文件,其中“文件类型指针”(简称“文件指针”)是一个非常重要的概念。
每一个被使用的文件都会在内存中开辟一个相应的文件信息区,用于存放文件的相关信息(文件名主体、状态、路径等等),这些信息被保存在一个结构体变量中,而这个由系统声明的结构体类型就是FILE,比方说某环境下stdio.h中就有这样的声明(不同环境下大同小异):
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
程序每当打开一个文件,系统就根据文件的情况创建一个FILE类型的结构体变量,并填充其中的信息。而一般我们使用一个FILE*类型的指针来维护这个FILE类型的结构体变量,而这就是我们实现程序与文件之间通讯的基础,也就是C语言中流的实质
文件指针变量可以指向某个文件的文件信息区(一个结构体变量),这样我们就可以通过文件信息区的信息访问和操作文件
文件在读写前应该先打开,在使用结束后应该关闭
ANSIC规定fopen函数用于打开文件,fclose函数用来关闭文件,原型如下:
#include <stdio.h>
FILE* fopen( const char* filename, const char* mode );
int fclose( FILE* stream );
fclose函数就是关闭stream指针指向的文件,成功则返回0,失败则返回EOF
关闭文件的实质是:将已经写到输入缓冲区的信息冲入、已经写到输出缓冲区的信息冲出;将尚未写入缓冲区的信息舍弃;最后取消该文件指针与文件的关联
(前两步其实就是刷新缓冲区,缓冲区相关知识下面会讲)
fopen函数就是以mode模式打开filename指向的文件,并返回一个指向该文件的FILE*指针
如果打开文件失败则返回空指针NULL并设置对应的errno
filename如果包含路径,则会寻找到对应的路径;如果不包含路径,就直接在本目录下(在Windows下表现为在本文件夹下)打开
mode称为文件访问模式字符串,其值与文件打开模式的对应关系如下:
文件访问模式字符串 | 含义 | 解释 | 若文件已存在 | 若文件不存在 |
---|---|---|---|---|
"r" | 只读 | 打开文件以读取 | 从头开始读 | 打开失败报错 |
"w" | 只写 | 创建文件以写入 | 销毁内容重写 | 创建新文件 |
"a" | 只后附 | 后附到文件 | 从结尾开始写 | 创建新文件 |
"r+" | 读扩展 | 打开文件读写 | 从头开始读写 | 打开失败报错 |
"w+" | 写扩展 | 创建文件读写 | 销毁内容重新读写 | 创建新文件 |
"a+" | 后附扩展 | 打开文件读写 | 从头开始读 从结尾开始写 | 创建新文件 |
标签b:在文件访问模式字符串后加一个b则代表以二进制模式进行(只有Windows下),b是和+类似的后缀所以顺序不影响。比如说:"wb+"和"w+b"都代表创建二进制文件读写,其行为与"w+"也是一样的。 | ||||
标签t:其实如果没有特意去加标签b,就默认后面有标签t,代表以文本的模式进行。比方说"a+"其实就是"a+t"或者"at+" | ||||
后缀x:在基于"w"的文件访问模式字符串的结尾加上x就代表如果文件已经存在的话,不再销毁内容重新写/读写,而是直接认为函数失败并返回NULL |
注意:
在更新模式(存在标签"+")下打开文件时:
(这部分相关的内容后面讲,涉及到缓冲区、文件定位函数等知识。暂且先列在这里,原因后面缓冲区那里再说。)
文件打开的模式与其返回的文件指针的权限息息相关,比如"w"和"a"模式下文件指针是无效的;"w+"和"a+"模式下文件指针只对读有效,如果写,文件指针就会自动移到文件尾
下面就是在本目录下创建一个abc.txt并写入字母表的程序:
#include <stdio.h>
int main()
{
FILE* pf = fopen("abc.txt", "w");
if (pf == NULL)
{
perror(fopen);
return 1;
}
for (int i = 0; i < 26; i++)
fputc('a' + i, pf);
fclose(pf);
pf = NULL;
return 0;
}