当调用open函数去打开文件的时候,内核会申请一段内存(一段缓冲区),并且将静态文件的数据内容从磁盘这些存储设备中读取到内存中进行管理、缓存(也把内存中的这份文件数据叫做动态文件、内核缓冲区)。打开文件后,对该文件的读写操作,都是对内存中这一份动态文件进行相关操作,并不是对磁盘中存放的静态文件操作。
当对动态文件进行读写操作后,此时内存中的动态文件和磁盘设备中的静态文件就不同步了,数据的同步工作由内核完成,内核会在之后将内存这份动态文件更新(同步)到磁盘设备中。比如说:打开一个大文件的时候会比较慢;正在编写的文档没保存,此时电突然停电直接关机了,重启电脑后,之前写的内容已经丢失。
这样设计是因为磁盘、硬盘、U盘等存储设备基本都是Flash块设备,块设备硬件本身有读写限制等特征,是以块为单位进行读写的(一个块包含多个扇区,而一个扇区包含多个字节),一个字节的改动也需要将该字节所在的块全部读取出来进行修改,修改完成之后再写入块设备中,这样会导致对块设备的读写操作非常不灵活。而内存可以按字节为单位来操作,并且可以随机操作任意地址数据,非常地灵活,读写速率远比磁盘读写快得多,所以对于操作系统来说,会先将磁盘中的静态文件读取到内存中进行缓存,读写操作都是针对这份动态文件。,
在Linux系统中,内核会为每个进程设置一个专门的数据结构用于管理该进程,用于记录进程的状态信息、运行特征等,这个被称为进程控制块(Process control block,缩写PCB)。PCB 数据结构体中有一个指针指向了文件描述符表(File descriptors),文件描述符表中的每一个元素索引到对应的文件表(File table),文件表也是一个数据结构体,其中记录了很多文件相关的信息,比如文件状态标志、引用计数、当前文件的读写偏移量以及 inode指针(指向该文件对应的inode)等,进程打开的所有文件对应的文件描述符都记录在文件描述符表中,每一个文件描述符都会指向一个对应的文件表。
inode数据结构体中的元素会记录该文件的数据存储的block(块),也就是说可以通过inode找到文件数据存在在磁盘设备中的那个位置,从而把文件数据读取出来。
|
|