目录
一、文件系统的结构
(1)物理结构
(2)逻辑结构
1.i节点
注意:每一个文件或者目录都有唯一的一个i节点与之对应(唯一编号)
文件名和i节点的对应关系记录在该文件所在目录的目录文件中,而这就是一个硬链接
2.数据块
访问一个文件首先要找到其对应的i节点,然后通过i节点号,在物理内存中找到其存储位置。然后开始解读i节点,通过i节点中存储的数据块(直接块和间接块)再来得到文件所存储的数据
二、文件的打开和关闭
(1)open
我们看到这里成功的创建了文件open.txt并且可以知道这个文件描述符fd的值是3
那么为什么是3呢?因为一个进程默认会打开三个文件:标准输入、标准输出、标准错误,所以我们再次打开的文件的下标就是3啦
(2)关闭文件
三、文件的读写
(1)write
(2)read
四、文件的顺序读写和随机读写
lseek函数
注意:因为文件的读写位置是保存在文件表项中,而不是v节点的,因此多次打开同一个文件,得到的多个文件描述符,各自拥有各自的文件读写位置。
这里说明:如果文件的读写位置在文件尾之后,但是由于文件目前还没有那么大,会在超过文件尾的位置填上0,这个我们称为文件空洞(尽管文件空洞不占用磁盘空间,但仍然会被计算在文件的大小之内)
五、文件的内核结构
划重点:
(1)无论打开多少次文件,都只会在系统内核中产生一个v节点,但是会有独立的文件表项
(2)close函数实际上是释放文件描述符,当该文件的所有文件描述符都被释放了,这个文件才会被关闭
六、文件描述符
(1)文件描述符的定义
(2)文件描述符的复制
那么文件描述符的复制有什么用呢?
我们都知道一个程序会默认打开三个文件:标准输入、标准输出、标准错误。但是我们并不知道他们在哪。
我们可以先把他们复制一份到文件描述符表中,然后关闭其原本的位置,用另外的文件去取代他们,做到printf打印到其他文件的效果,在使用完成后,只需要再次将副本回归到原来位置,就能让系统回归正常状态。
我们一般在打印文件日志的时候会这样做。所以文件描述符的复制最大的用处就是保证了数据的安全性,防止关闭了一个文件描述符后找不到该文件表项了。
七、访问测试
我们可以使用这个函数来判断当前进程是否有对某个文件的特定权限,为了更好的使用这个函数,我们可以使用命令行参数来丰富我们的选择
在这里我们只写出了判断读权限的访问测试,大家有兴趣的话可以写出完整的一套测试逻辑
八、修改文件大小
这个一般要和内存映射文件相结合使用,如果只映射了但是文件大小为0也是写不了的
九、文件锁
(1)文件锁的定义和使用
(2)文件锁的内核结构
十、内存映射文件
内存映射文件和映射到物理内存其实没有太大区别,无非就是一个对应着文件的访问操作,一个对应着物理内存的访问操作。
当我们对文件或者是物理内存进行了映射之后才能使用操作系统来对其进行一系列的访问操作。其实前面的write/read等文件操作和malloc/sbrk等内存操作底层都是封装了mmap的。