Linux文件与fd
1,回顾c语言的文件接口
fopen:
在图中我们重点讲w和a,其他的大同小异:
我们可以用fopen打开创建文件,如果用到w方法来打开文件,如果文件存在,就会清空原来的内容来写入新的内容:
然后我们来改一下massage的数据:
可以看到,原来的数据被清空了,再写入新的数据。
如果用a方法来打开文件,就不会对文件进行清空处理,而是追加:
2,初步了解文件的系统调用接口
open接口,利用位图的方式来调用O_RDONLY等函数
常见的文件操作的指令有以下几种:
首先我们要用只写的方式来打开文件:
可以看到,如果文件存在就会直接打开写入
但是如果文件不存在:
会发现,运行程序之后不会帮我创建文件写入,open失败那么我们就要用到指令:O_CREAT来进行判断,如果文件不存在则创建文件,如果文件存在则直接打开文件写入:
可以看到创建了一个text5的文本文件,但是他说权限和我们用c创建文件时的权限不一样,这个时候我们就要了解以下有三个参数的open:
第三个参数的作用就是修改文件的权限:
可以看到,text5文本的权限被改变,但是问题来了,我输入的是0666,为什么权限是0664呢?
因为每个运行的程序都是一个进程,进程中有一个权限补齐的操作:umask,如果在程序中没有给umask初始化,就会默认使用系统的权限补齐:
那么如果我们在程序中加入umask(0):
可以看到,text5文本的权限变成了0666,那么我们在代码中运行的umask会影响系统的umask吗?
现然不会。
3,利用前面知识完成Linux指令:touch的编写
可以看到和touch创建的文件基本一样。
4文件内容清空和文件内容追加:
1,文件内容清空
在open中输入O_TRUNC,表示在如果文件为空则创建文件,如果不为空则清空内容在写入:
2,文件内容追加
在open中输入O_APPEND,表示在如果文件为空则创建文件,如果不为空则追加内容:
5,open函数返回值
上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
而, open close read write lseek 都属于系统提供的接口,称之为系统调用接口
1,文件描述符fd
可以看到,我们打开的文件的返回值是从3到7,那么我们猜测操作系统管理文件是以数组的方式管理,那么0,1,2呢?为什么下标会从3开始?
因为进程在启动的时候默认启动了三个流,分别是:
stdin :标准输入
stdout:标准输出
stderr:标准错误
那么我们是否可以直接用数组下标的方式写入?:
可以看到,可以向屏幕输入我们的内容
所以fd究竟是什么?就是数组下标!
用一张图来理解进程与文件的关联:
因为进程与文件不能高耦合,我们操作系统用双链表对我们的文件进行管理,通过数组下标返回给进程,也就是说对文件的管理变成了对链表的增删查改,所以通过fd_array数组与进程关联起来,实现了用指针与进程关联起来和解耦
进程:文件 == 1:多
所以在系统层面,fd是访问文件的唯一方式!!!
6,什么是FILE?
很明显file与系统接口无关,只是c实现的一个结构体,在file结构体中就有指向fd的下标: