文章目录
前言
我们现在要学习的文件可以分为两类,一类是在内存中的文件,另一类是在磁盘中的文件。
一、内存中的文件
我们如果想要对文件内容进行操作,或者创建关闭文件,首先得把这个文件加载到内存中,变成进城之后,再进行操作。这一个进程中可能会存在多个被打开的文件,操作系统肯定要管理这些被打开的文件,先描述,在组织
1.回顾c语言
在c语言我们学习过文件fopen,fclose相关的接口函数。
我们来看几个经典的方法
🌟🌟读方法
我们首先在log.txt中放入一些内容
我们看一下r方法
我们用下面代码做一下测试
进行运行之后
🌟🌟写方法
我们首先看一下w方法的说明
如果该文件不存在会自动创建,并且fp指针指向起始位置,也就是说每次我们运行都会清空原内容,重新开始写入。
我们发现确实完成了相应的操作。
🌟🌟追加方法
看一下a方法的文档,从fp的末尾开始
用下面代码做一下测试
看一下预期效果。
c语言默认打开三个流:标准输入(键盘)stdin,标准输出(显示器)stdout,标准错误(显示器)stderr
这三个都是FILE类型的指针
进程启动时都会记录自己所在的路径
2.系统调用
我们如果想对文件进行操作,必须加载到内存,访问系统里面的数据,必须经过系统调用。
打开文件的系统调用函数是open函数,还有其他write,read,close系统调用,这里小编就不一个个叙述了,主要讲解open函数
🌟使用这个系统调用必须包含相应的头文件
🌟我们这里有两个open函数,到底该用哪个呢??
如果我们明确知道文件存在了,我们就用第一个。
如果文件不存在我们就用第二个。
🌟pathname就是我们要操作的文件名
🌟flags相当于标记位,可以传入多个参数,这些参数之间进行或操作,构成flags。我们详细看一下几个常用的:
追加操作
如果文件不存在将会被创建,需要使用mode,表示新文件权限
清空文件
读写操作
🌟返回值
成功返回文件描述符(后面介绍),失败返回-1。
💝 💝 写操作
文件不存在就创建,每次清空文件,设置文件权限664。
我们运行看一下
符合我们的预期,我们可以发现这不就是我们c语言中的w(写)操作吗!!!确实是这样的,c语言的函数封装了系统调用。
我们也可以在代码中修改umask
💝 💝 追加操作
我们只需要稍微修改一下就可以
追加操作完成
💝 💝 读操作
我们先往test.txt放入一些内容
用read方法进行读取
运行结果
我们可以发现上面的三种方法和c语言的极其类似,c语言的函数本质就是封装了系统调用
为什么要折磨做呢???
主要是为了保证跨平台型(不同平台都可以正常使用),不用关心底层差异
3.文件描述符
我们首先创建几个文件,看看文件描述符
我们发现fd并没有从0开始,而是直接到达了3。
Linux下默认打开三个文件描述符:
🌟0表示标准输入,也就是键盘
🌟1表示标准输出,也就是显示器
🌟2表示标准错误,也就是显示器
我们画张图来理解一下文件描述符
一个进程可能要打开多个文件,同时对这些文件进行管理。先描述(file),在组织(数据结构)。
这些file的指针被存放在一个files_struct中的一个数组中,数组下标从0开始。PCB里面存放着files_struct的指针,所以我们就可以通过PCB快速找到这个文件进行操作。
文件描述符就是数组下标。
我们把这个文件描述符返回给上层直接使用,就可以对相应的文件进行操作。
深度理解Linux下一切皆文件
每个文件都有自己的属性和方法,例如显示器文件,他只有读方法,没有写方法,我们就把这个写方法设置为空。
本质就是通过屏蔽底层差异实现的,上层使用统一的接口,类似与多态调用
文件描述符分配规则:在file_struct数组中,找到当前没有被使用的最小的数组下标,作为新的文件描述符
4.重定向
我们先看一下下面代码
我们正常运行一下看看会发生什么
我们发现printf本来应该向显示器打印内容,现在打印到了file.txt文件中!!!
这是因为我们关闭了文件描述符1,也就是显示器文件,现在新的file.txt文件会用最小的并没有使用的下标,就使用了文件描述符1。
printf是c语言的库函数,本来就应该向stdout打印内容,但是stdout底层是1号文件描述符,所以向1号文件描述符写入,现在1号文件描述符指向了file.txt文件,所以最终就向file.txt里边写入。
重定向本质就是文件描述符(指针)的指向的改变.
想对系统内核数据进行修改,必定封装了系统调用
把oldfd中的内容拷贝到newfd中,最终只剩下oldfd.
我们也可以通过这种方式实现重定向的功能。
5.缓冲区
缓冲区是什么呢??缓冲区就是一块内存空间。
缓冲区有什么用呢??提高使用者的运行效率,同时数据整合,提高整体效率
缓冲区存在哪里呢??c语言层面存在于FILE结构体中
FILE结构中中肯定也封装文件描述符fd.
我们来详细介绍一下缓冲区
🌟c语言层面有缓冲区。操作系统层面也有缓冲区,只不过这个是由操作系统自己管理的,我们这里不过多介绍。
🌟我们知道,系统调用是有开销和消耗的,所以我们要尽量减少系统调用。
���