|
静态文件与 inode 文件在没有被打开的情况下一般都是存放在存储设备中,比如硬盘、U盘等存储设备。静态文件则是指:存放在磁盘文件系统中,并且以一种固定的形式进行存放的文件。 文件储存在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector),每个扇区储存512字节(相当于 0.5KB),操作系统读取硬盘的时候,不会一个一个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取的最小单位。“块”的大小,最常见的是4KB,即连续八个sector组成一个block。 静态文件对应的数据都是存储在磁盘设备不同的“块”中。 磁盘在进行分区、格式化的时候会分为两个区域,一个是数据区,用于存储文件中的数据;另一个是inode区,用于存放inode table(inode表),inode table中存放的是一个一个的inode(也叫做inode节点),不同的inode就可以表示不同的文件,每一个文件都必须对应一个inode,inode实质上是一个结构体,这个结构体中有很多的元素,不同的元素记录了文件的不同信息,譬如文件字节大小、文件所有者、文件对应的读/写/执行权限、文件时间戳(创建时间、更新时间等)、文件类型、文件数据存储的block(块)位置等信息。 inode table表本身也需要占用磁盘的存储空间。每一个文件都有唯一的inode,每 一个inode都有一个与之相对应的数字编号,通过这个数字编号就可以找到inode table中所对应的inode。在Linux系统下,可以通过"ls -i"命令查看文件的inode编号: $ ls -i 5374043 ftest 5374017 test 5374045 test.c 打开一个文件,系统内部会将这个过程分为三步: ① 系统找到这个文件名所对应的inode编号。 ② 通过inode编号从inode table中找到对应的inode结构体。 ③ 根据inode结构体中记录的信息,确定文件数据所在的block,并读出数据。 文件打开时的状态 当调用open函数去打开文件的时候,内核会申请一段内存(一段缓冲区),并且将静态文件的数据内容从磁盘这些存储设备中读取到内存中进行管理、缓存(也把内存中的这份文件数据叫做动态文件、内核缓冲区)。打开文件后,对该文件的读写操作,都是对内存中这一份动态文件进行相关操作,并不是对磁盘中存放的静态文件操作。 当对动态文件进行读写操作后,此时内存中的动态文件和磁盘设备中的静态文件就不同步了,数据的同步工作由内核完成,内核会在之后将内存这份动态文件更新(同步)到磁盘设备中。比如说:打开一个大文件的时候会比较慢;正在编写的文档没保存,此时电突然停电直接关机了,重启电脑后,之前写的内容已经丢失。 这样设计是因为磁盘、硬盘、U盘等存储设备基本都是Flash块设备,块设备硬件本身有读写限制等特征,是以块为单位进行读写的(一个块包含多个扇区,而一个扇区包含多个字节),一个字节的改动也需要将该字节所在的块全部读取出来进行修改,修改完成之后再写入块设备中,这样会导致对块设备的读写操作非常不灵活。而内存可以按字节为单位来操作,并且可以随机操作任意地址数据,非常地灵活,读写速率远比磁盘读写快得多,所以对于操作系统来说,会先将磁盘中的静态文件读取到内存中进行缓存,读写操作都是针对这份动态文件。, 在Linux系统中,内核会为每个进程设置一个专门的数据结构用于管理该进程,用于记录进程的状态信息、运行特征等,这个被称为进程控制块(Process control block,缩写PCB)。PCB 数据结构体中有一个指针指向了文件描述符表(File descriptors),文件描述符表中的每一个元素索引到对应的文件表(File table),文件表也是一个数据结构体,其中记录了很多文件相关的信息,比如文件状态标志、引用计数、当前文件的读写偏移量以及 inode指针(指向该文件对应的inode)等,进程打开的所有文件对应的文件描述符都记录在文件描述符表中,每一个文件描述符都会指向一个对应的文件表。 inode数据结构体中的元素会记录该文件的数据存储的block(块),也就是说可以通过inode找到文件数据存在在磁盘设备中的那个位置,从而把文件数据读取出来。
|