文章目录
一、文件描述符
1.文件的认识
无论在什么操作系统下,文件 = 文件内容 + 文件属性,其中文件内容是数据,文件属性也是数据,也就是说如果你创建了一个空文件,里面没有任何内容,它也是要占据磁盘空间的,因为文件存在属性信息。
因此,我们后续做的所有文件操作,实质上是对文件内容操作或者对文件属性的操作。
我们之前在学习C语言文件操作的内容时,每次对文件的操作,一定是先要打开文件,这里的打开文件实质上是将文件的属性或者内容加载到内存中(因为根据冯诺依曼体系结构,CPU只能读取内存的数据)。而操作系统中一定还存在着很多没有被打开的文件,这些没有被打开的文件一定是在磁盘上存储着的。
因此,我们操作系统里的所有文件,在宏观上可以分为“打开的文件(内存文件)”和“磁盘文件”两类。
通常我们做的文件操作例如打开文件、关闭文件,读写文件等,是我们在写代码的时候调用相关的文件操作函数,这些文件操作函数帮我们实现的文件操作。但更深入一层次地理解,并不是我们所写的代码在进行文件操作,而是我们所写的代码变成程序运行起来以后,执行相应的文件操作代码,然后才会完成对文件的操作。
因此,这本质上是进程在进行文件操作!
2.C语言下的文件操作
由于本篇博客主要介绍的是操作系统层面的文件知识,所以我们会频繁使用到文件操作的方法,下面我们先来复习一下C语言的文件操作方法。
(1)文件指针
我们对文件进行操作,首先得要有该文件的文件指针。每一个被使用的文件都会在内存中开辟一个相应的文件信息区,用来存放文件的相关信息。和我们之前提到的管理的本质相同,也是 先描述再组织 ,描述文件的信息是保存在结构体当中的,这个结构体的指针就是文件指针。
(2)文件的打开和关闭
C语言中文件打开用的是fopen函数:
- 返回值:如果文件打开成功,则返回该文件的文件指针,否则返回NULL
- const char *filename:传入需要打开的文件地址
- const char *mode:文件打开的方式
文件的打开方式决定的是该文件打开以后是否可读、是否可写,以及怎么写,具体的打开方式如下:
- “r”(只读):只有读取文件数据的权限,不可以对文件进行任何形式的写入(如果指定文件不存在会报错)
- “w”(格式化写入):可以对文件进行写入,属于格式化写入,会先清空文件内容再写入(如果指定文件不存在会新建一个文件)
- “a”(追加写入):可以对文件进行写入,属于追加写入,会在文件内容末尾追加写入数据,并不会清空文件原有的数据(如果指定文件不存在会新建一个文件)
- “r+”(读写打开):这是在“r”方式的基础上加入了写功能,也就是读写打开,这种方式打开文件以后不会清空文件原有的内容,且写入内容时可以在文件的任意位置写入(如果指定文件不存在会报错)
- “w+”(读写打开):这也是读写打开的方式,同样也是写入内容时可以在文件的任意位置写入区别在于这种方式打开文件以后会清空原有的内容(如果指定文件不存在会新建一个文件)
- “a+”(读写打开):这也是读写打开的方式,这种方式打开不会清空文件原有的内容,但在写入内容时只能够在文件末尾写入(如果指定文件不存在会新建一个文件)
关闭文件使用的是fclose函数:
- 返回值:关闭成功返回0,否则返回EOF
- FILE *stream:需要关闭的文件指针
(3)文件顺序写入函数
文件写入函数是将数据写入到文件当中的,顺序写入的意思是按照从前往后的顺序,先写入的数据在前面,后写入的数据在后面,类似于顺序表的尾插操作。
第一个顺序写入函数是fprintf函数
- 返回值:如果写入成功,则返回写入的字符个数,否则返回EOF
- FILE *stream:要输出的流(即数据要写入到哪里)
- char *format[, argument, …]:要输出的格式,为可变参数
- 功能:格式化地将数据写入到指定的流中,输出格式与printf函数一样,每遇到一个%,就按规定的格式,依次输出argument的值到流stream中
下面我们用代码演示一下fprintf函数:
我们打开一个文件,用fprintf函数向文件写入一个字符串“hello myfile”以及一个整型数。
代码运行起来以后我们查看刚刚操作的文件内容,字符串与数字确实被写入到了文件中。
第二个顺序写入函数是fputs函数
- 返回值:如果写入成功,则返回一个非负值,否则返回EOF
- char *str:要写入到文件里的字符串
- FILE *stream:要写入的流,即写入到哪个地方
- 功能:将一个以’\0’结尾的字符串送入指定的流中,不加换行符‘\n’和结束符’\0’
下面我们用地代码演示一下fputs函数:
我们打开一个文件,用fputs函数向文件写入一个字符串str(手动带上换行符)
代码运行起来以后我们查看一下刚刚操作的文件内容,str字符串确实被写入到了指定的文件中。
第三个顺序输入函数是fputc函数
- 返回值:如果写入成功,则返回写入的字符(以int形式返回),否则返回EOF
- int ch:以int形式传递需要写入的字符
- FILE *stream:要写入的流
下面我们用代码演示一下fputc函数:
我们打开一个文件,用fputc函数向文件写入字符ch,让ch从字符A开始不断加加,写入26个大写字母(手动添加换行符,方便查看结果)
代码运行起来以后我们查看一下刚刚操作的文件内容,26个大写英文字母(以及换行符)确实被写入到了指定的文件中。
(4)文件顺序读取函数
文件读取函数就是将数据从文件中读取出来,顺序读取是从文件头开始按顺序依次往后读取,类似于顺序表的遍历访问操作。
第一个顺序读取函数是fscanf函数
- 返回值:如果读取成功,则返回读取的字符个数,否则返回EOF
- FILE *stream:要读取的流(即要到哪里去读取)
- char *format[, argument, …]:要按什么