共识原理:
1.文件 = 内容 + 属性
2.文件分为打开的文件 和 没打开的文件
3.打开的文件: 谁打开? 进程! ----本质是研究进程和文件的关系!
根据冯诺依曼原理,文件被打开,必须先被加载到内存!不然CPU怎么访问它
那么是文件内容被加载?还是属性被加载?还是都被加载?
一定要先把属性加载到内存,内容要不要被加载取决于要不要对文件做修改,理想情况是都被加载
一个进程可以打开多个文件,则进程与打开文件数量关系为
进程:打开的文件 = 1 :n
则操作系统内部,一定存在大量的被打开的文件!
------0S要不要管理这些被打开的文件呢? ----怎么管理???—先描述,在组织 — 在内核中,一个被打开的文件都必须有自己的文件打开对象,包含文件的很多属性。struct XXX{文件属性; struct XXX*next}; 用双链表组织起来
4.没打开的文件:∶在哪里放着呢? 在磁盘上。我们最关注什么问题?没有被打开的文件非常多。文件如何被分门别类的放置好…我们要快速的进行增删查改…快速找到文件
如何存储?
本文目标主要先研究被打开的文件
1、以C语言为主,先回忆一下C文件接口
打开文件的路径和文件名,默认在当前路径下新建一个文件,fopen中当前路径是什么?
当前路径,进程的当前路径cwd —如果我更改了当前进程的cwd(chdir),就可以把文件新建到其他目录
ls /proc/进程ID 可以查看进程task_stuct的绝大多数属性,cwp就是进程环境变量pwd改了个名字来的
下面用fwrite进行写入一段字符串
更改字符串由hello linux -> abcd 发现并不是abcdo linux 而是只有abcd
w方式打开的特性:
如果以w方式打开,如果文件不存在会创建一个
w : 写入之前,会对文件进行清空处理,并且从文件开始写入
观察输出重定向,盲猜一波它本质一定是打开这个文件并且是w模式打开的,因为他会先清空
问题:对文件进行写入字符串时,要不要把\0也加上?
答:字符串以\0结尾,是你C语言的规定,和我文件有什么关系? ??
a 方式打开 追加写
则 > 和 >> 一定是打开方式的区别 w / a
C程序默认再启动的时候帮我们打开三个流,标准输入stdin,标准输出stdout,标准错误stderr
这三个输入输出流就是文件
在C语言看来 向显示器写入和向文件写入没有区别
因为Linux下一切皆文件,所以我们可以不用printf,直接用文件fprintf等接口直接向显示器写入
那么问题来了
1、如何理解 Linux一切皆文件?
2、三个标准流为什么所有语言都要支持,它到底是什么?怎么做到的?
2、过渡到系统,认识文件系统调用
文件在磁盘上,磁盘是外部设备,访问文件其实是在访问硬件!
根据计算机体系层状结构和操作系统不相信任何用户,则C语言访问文件的库函数一定封装了文件系统调用接口!利用系统调用贯穿操作系统访问硬件
认识几个文件系统调用
1、open
对于flags是标志位,代表只写/追加/没有创建新文件/清空…
我们要是自己写可能在形参直接干上2~3以上标志位,但其实一个整形本来就有32位,可以利用一个Bit位代表一个状态
我们可以用一种优雅的方式来完成这个工作。做到只传一个int flags来完成标记
手册中看到O_RDONLY,O_WRONLY,这一看就是个宏,只有一个bit位是1,代表不同的状态!
比特位级别的标志位传递方式:
falgs提供了很多宏,只有一个Bit位为1,他可以传递多种标志位做按位或的组合,在函数内部再一与,就可以调用不同的功能函数
再回到open上来
1、O_WRONLY不会创建文件,如果文件不存在就打开失败,open返回值为-1,则需要或上O_CREAT
2、即使标志位为O_WRONLY|O_CREAT 新建文件权限为随机值,所以创建文件必须告诉Open第三个形参权限
0666为八进制,rw- rw- rw- ,可结果是664 那么是因为掩码的存在
umask默认002 也是八进制 可以通过更改umask的方式来就让文件权限是666
系统调用umask
3、访问文件的本质
4、重定向 && 缓冲区