• 408操作系统知识点——第四章 文件管理



    注:内容参考王道2024考研复习指导

    初识文件管理

    文件的定义:文件就是一组有意义的信息/数据集合

    文件的属性:包括文件名、标识符、类型、位置、大小、保护信息等。

    文件内部的数据组织:分为无结构文件(流式文件)和有结构文件(记录式文件)。

    文件之间的组织:系统中的各个文件通过一层一层的目录合理有序的组织起来。

    操作系统向上提供的功能:create、delete、open、close、read、write系统调用。

    文件在外存的存放:外存会分为一个个“块/磁盘块/物理块”,操作系统以“块”为单位为文件分配存储空间。

    :系统运行时,计算机以进程为基本单位进行资源的调度和分配;输入输出时,则以文件为基本单位。

    文件的逻辑结构

    “逻辑结构”就是在用户看来,文件内部的数据应该是如何组织起来的。

    “物理结构”指的是在操作系统看来,文件的数据是如何存放在外存中的。

    无结构文件

    无结构文件是最简单的文件组织形式。

    文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。如:Windows操作系统中的.txt文件。

    文件内部的数据其实就是一系列字符流,没有明显的结构特性。因此也不探讨无结构文件的“逻辑结构”问题。

    有结构文件

    由一组相似的记录组成,又称“记录式文件”。

    每条记录又若干个数据项组成。一般来说,每条记录有一个数据项可作为关键字(作为识别不同记录的ID),如:数据库表文件。

    根据各条记录的长度(占用的存储空间)是否相等,又可分为定长记录和可变长记录两种。

    • 定长记录。文件中所有记录的长度都是相同的,各数据项都在记录中的相同位置,具有相同的长度。检索记录的速度快,方便用户对文件进行处理,广泛用于数据处理中。
    • 变长记录。文件中各记录的长度不一定相同,原因可能是记录中所包含的数据项数目不同,也可能是数据项本身的长度不定。检索记录只能顺序查找,速度慢。

    顺序文件

    文件中的记录一个接一个地顺序排列(逻辑上),记录可以是定长的或可变长的。

    顺序文件按记录的排列顺序可以分为串结构和顺序结构。

    • 串结构,各记录之间的顺序与关键字无关,通常是按存入的先后时间进行排列,检索时必须从头开始顺序依次查找,比较费时。
    • 顺序结构,所有记录按关键字顺序排列,对于定长记录的顺序文件,检索时可采用折半查找,效率较高。

    记录在物理上即可以顺序存储(逻辑上相邻的记录物理上也相邻)也可以链式存储(逻辑上相邻的记录物理上不一定相邻)。

    image-20240524211829440

    只有定长记录的顺序文件且在物理上采用顺序存储,才可以实现随机存取,如果再采用顺序结构,则可实现快速检索(即根据关键字快速找到对应记录)。

    :试题中所说的“顺序文件”指的是物理上顺序存储的顺序文件。

    索引文件

    很多应用场景中必须使用可变长记录,为了快速检索,可以采用索引文件快速找到第i个记录。

    image-20240524212747892

    索引表本身是定长记录的顺序文件,可以快速找到第i个记录对应的索引项。

    可将关键字作为索引号内容,若按关键字顺序排列,则还可以支持按照关键字折半查找。

    每当要增加/删除一个记录时,需要对索引表进行修改。由于索引文件有很快的检索速度,因此主要用于对信息处理的及时性要求比较高的场合。

    另外,可以用不同的数据项建立多个索引表。如:学生信息表中,可用关键字“学号”建立一张索引表。也可用“姓名”建立一张索引表。这样就可以根据“姓名”快速地检索文件了。

    索引顺序文件

    索引顺序文件是索引文件和顺序文件思想的结合。

    索引顺序文件中,会为文件建立一张索引表,但并不是每个记录对应一个索引表项,而是一组记录对应一个索引表项。

    image-20240524213246473

    上图案例中,学生记录按照学生姓名的开头字母进行分组。

    每个分组就是一个顺序文件,分组内的记录不需要按关键字排序。

    索引顺序文件的索引项也不需要按关键字顺序排列,这样可以极大地方便新表项的插入。

    多级索引顺序文件

    image-20240524213423081

    要为N个记录的文件建立K级索引,则最优的分组是每组N1/(K+1)个记录。检索一个记录的平均查找次数是((N1/(K+1) )/2) * (K+1)。

    直接文件或散列文件

    给定记录的键值或通过散列函数转换的键值直接决定记录的物理地址。散列文件具有很高的存取速度,但是会引起冲突,即不同关键字的散列函数值可能相同。

    文件目录

    在Windows操作系统下文件目录即“文件夹”。

    文件控制块

    文件控制块

    文件控制块(FCB)是用来存放控制文件需要的各种信息的数据结构,文件与FCB一一对应。

    FCB中包含了文件的基本信息(文件名、物理地址、逻辑结构、物理结构等),存取控制信息(是否可读/可写、禁止访问的用户名单等),使用信息(如文件的建立时间、修改时间等)。

    image-20240525220326171

    最重要,最基本的还是文件名、文件存放的物理地址。FCB实现了文件名和文件之间的映射。使用户(用户程序)可以实现按名存取

    文件目录

    FCB的有序集合称为“文件目录”,一个FCB就是一个文件目录项。

    目录文件

    为了实现对文件目录的管理,通常将文件目录以文件的形式保持在外存,这个文件就叫目录文件。目录文件中的一条记录就是一个FCB。

    索引结点

    索引节点(i节点,inode)是对FCB的改进。

    在查找各级目录的过程中只需要用到“文件名”这个信息,只有文件名匹配时,才需要读出文件的其他信息。因此可以考虑让目录表“瘦身”来提升效率。

    image-20240524215845919

    当找到文件名对应的目录项时,才需要将索引结点调入内存,索引结点中记录了文件的各种信息,包括文件在外存中的存放位置,根据“存放位置”即可找到文件。

    存放在外存中的索引结点称为“磁盘索引结点”,当索引结点放入内存后称为“内存索引结点”。

    磁盘索引节点

    是指存放在磁盘上的索引节点。每个文件有一个唯一的磁盘索引节点,主要包括以下内容:

    • 文件主标识符,拥有该文件的个人或小组的标识符。
    • 文件类型,包括普通文件、目录文件或特别文件。
    • 文件存取权限,各类用户对该文件的存取权限。
    • 文件物理地址,每个索引节点中含有13个地址项,即iaddr(0)~iaddr(12),它们以直接或间接方式给出数据文件所在盘块的编号。
    • 文件长度,指以字节为单位的文件长度。
    • 文件链接计数,在本文件系统中所有指向该文件的文件名的指针计数。
    • 文件存取时间,本文件最近被进程存取、修改的时间及索引节点最近被修改的时间。

    内存索引节点

    是指存放在内存中的索引节点。当文件被打开时,要将磁盘索引节点复制到内存的索引节点中,便于以后使用。在内存索引节点中增加了以下内容:

    • 索引节点号,用于标识内存索引节点。
    • 状态,指示i节点是否上锁或被修改。
    • 访问计数,每当有一进程要访问此i节点时,计数加1;访问结束减1。
    • 逻辑设备号,文件所属文件系统的逻辑设备号。

    目录结构

    单级目录结构

    早期操作系统并不支持多级目录,整个系统中只建立一张目录表,每个文件占一个目录项。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    单级目录实现了”按名存取“,但不允许文件重名。

    在创建一个文件时,需要先检查目录表中有没有重名文件,确定不重名后才能允许建立文件,并将新文件对应的目录项插入目录表中。

    单级目录结构不适用于多用户操作系统。

    两级目录结构

    早期的多用户操作系统,采用两级目录结构。分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User Flie Directory)。

    image-20240524215049512

    主文件目录记录用户名及相应用户目录的存放位置。用户文件目录由该用户所有文件的FCB组成。

    两级目录结构允许不同用户的文件重名(文件名虽然相同,但是对应的其实是不同的文件),也可以在目录上实现实现访问限制(检查此时登录的用户名是否匹配)。

    两级目录结构缺乏灵活性,用户不能对自己的文件进行分类。

    多级目录结构

    又称树形目录结构,不同目录下的文件可以重名。

    image-20240524215136654

    用户(或用户进程)要访问某个文件时要用文件路径名标识文件,文件路径名是个字符串。各级目录之间用“/”隔开。从根目录出发的路径称为绝对路径。例如:自拍.jpg的绝对路径是/照片/2015-08/自拍.jpg

    当层次较多时,每次从根目录查询会浪费时间,于是可为每个进程设置一个当前目录(又称工作目录)。例如,此时已经打开了“照片”的目录文件,也就是说,这张目录表已调入内存,那么可以把它设置为“当前目录”。当用户想要访问某个文件时,可以使用从当前目录出发的相对路径

    在Linux中,“.”表示当前目录,因此如果“照片”是当前目录,则”自拍.jpg”的相对路径为:./2015-08/自拍.jpg

    树形目录结构可以很方便地对文件进行分类,层次结构清晰,也能够更有效地进行文件的管理和保护;但是增加了磁盘访问次数。

    无环图目录结构

    树形结构不便于实现文件的共享。为此,提出了“无环图目录结构”。

    在树形目录结构的基础上,增加一些指向同一节点的有向边,整个目录成为一个有向无环图,方便实现多个用户间的文件共享。

    image-20240524215546721

    可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。

    需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时,只是删除该用户的FCB,并使共享计数器减1,并不会直接删除共享结点。只有共享计数器减为0时,才删除结点。

    无环图目录结构方便地实现了文件的共享,但使得系统的管理变得更加复杂。

    :当建立链接关系时,必须将被共享文件的物理地址(盘块号)复制到相应的目录。如果某个用户向该文件添加新数据,且
    需要增加新盘块,那么这些新增的盘块只出现在执行操作的目录中,对其他共享用户是不可见的。(此问题的解决采用下文的索引节点

    文件共享

    文件共享使多个用户共享同一个文件,系统中只需保留该文件的一个副本。若系统不能提供共享功能,则每个需要该文件的用户都要有各自的副本,会造成对存储空间的极大浪费。

    基于索引节点的共享方式(硬链接)

    image-20240525131142252

    索引结点中设置一个链接计数变量count,用于表示链接到本索引结点上的用户目录项数。

    若count = 2,说明此时有两个用户目录项链接到该索引结点上,或者说是有两个用户在共享此文件。

    若某个用户决定“删除”该文件,则只是要把用户目录中与该文件对应的目录项删除,且索引结点的count值减1。

    若count>0,说明还有别的用户要使用该文件,暂时不能把文件数据删除,否则会导致指针悬空。

    当count = 0时系统负责删除文件。

    :引用计数值为1,说明有一个用户(文件主,即创建文件的用户)正在共享文件,但是不意味着文件被读入内存,只有文件被用户打开时才会读入内存。

    基于符号链的共享方式(软链接)

    image-20240525131310157

    当User3访问“ccc”时,操作系统判断文件“ccc”属于Link类型文件,于是会根据其中记录的路径(C:/User1/aaa)层层查找目录,最终找到User1的目录表中的“aaa”表项,于是就找到了文件1的索引结点。

    类似于Windows操作系统的“快捷方式”。

    即使软链接指向的共享文件已经被删除,Link型文件依然存在,只是通过Link型文件中的路径去查找共享文件会失败。

    由于用软链接的方式访问共享文件时要查询多级目录,会有多次磁盘I/O,因此用软链接访问共享文件的速度要比硬链接更慢。

    文件的物理结构

    文件的物理结构/文件分配方式主要探讨对非空闲磁盘块的管理(存放了文件数据的磁盘块)。

    磁盘块

    类似于内存分页,磁盘中的存储单元会被分为一个个块(磁盘块、物理块),磁盘块大小与内存块、页面的大小相同。

    内存与磁盘之间的数据交换(即读/写操作、磁盘I/O)都是以“块”为单位进行的。即每次读入一块,或每次写出一块。

    image-20240525080627954

    在内存管理中,进程的逻辑地址空间被分为一个一个页面。同样的,在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空间也被分为了一个一个的文件块。文件的逻辑地址也可以表示为(逻辑块号,块内地址)的形式。

    操作系统为文件分配存储空间都是以块为单位的,用户通过逻辑地址来操作自己的文件,操作系统负责实现从逻辑地址到物理地址的映射。

    连续分配

    连续分配要求每个文件在磁盘上占用一组连续的块。

    image-20240525080830730

    从(逻辑块号,块内地址)转换到(物理块号,块内地址)。只需转换块号,块内地址保持不变。

    文件目录中记录了文件的起始块号和长度,用户给出访问的逻辑块号,操作系统需要找到文件的FCB,物理块号=起始块号+逻辑块号,可直接算出逻辑块号对应的物理块号。即,连续分配支持顺序访问和直接访问(即随机访问)。

    优点:支持顺序访问和直接访问(即随机访问);连续分配的文件在顺序访问时速度最快。

    缺点:不方便文件拓展;存储空间利用率低,会产生磁盘碎片。

    链接分配

    链接分配采取离散分配的方式,可以为文件分配离散的磁盘块,分为隐式链接和显式链接两种。

    隐式链接

    image-20240525081518774

    除了文件的最后一个磁盘块之外,每个磁盘块中都会保存指向下一个盘块的指针,这些指针对用户是透明的。

    读入i号逻辑块,总共需要i+1次磁盘I/O。

    优点:很方便文件拓展,不会有碎片问题,外存利用率高。

    缺点:只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量的存储空间。

    :为了提高查找速度和减小指针所占用的存储空间,可以将几个盘块组成一个簇,按簇而不按块来分配(即一个文件所占用的空间只能是簇的整数倍),可以大幅地减少查找时间,也可以改善许多算法的磁盘访问时间。比如一簇为4块,这样,指针所占的磁盘空间比例也要小得多。这种方法的代价是增加了内部碎片。

    显式链接

    把用于链接文件各物理块的指针显式地存放在一张表中。即文件分配表(FAT,File Allocation Table)。

    image-20240525081840367

    一个磁盘仅设置一张FAT(FAT大小取决于磁盘大小)。开机时,将FAT读入内存,并常驻内存。FAT的各个表项在物理上连续存储,且每一个表项长度相同,因此“物理块号”字段可以是隐含的。

    从目录项中找到起始块号,若i>0,则查询内存中的文件分配表FAT,往后找到i号逻辑块对应的物理块号。逻辑块号转换成物理块号的过程不需要读磁盘操作。

    优点:很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接来说,地址转换时不需要访问磁盘,因此文件的访问效率更高。

    缺点:文件分配表的需要占用一定的存储空间。

    :试题中遇到未指明方式的链接分配,默认式隐式链接的链接分配。

    索引分配

    索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表(索引表大小取决于文件大小),索引表中记录了文件的各个逻辑块对应的物理块(类似于页表)。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    从目录项中可知索引表的存放位置,将索引表从外存读入内存,并查找索引表可找到i号逻辑块在外存中的存放位置。

    索引分配方式可以支持随机访问。文件拓展也很容易实现(只需要给文件分配一个空闲块,并增加一个索引表项即可),但是索引表需要占用一定的存储空间。

    若每个磁盘块1KB,一个索引表项4B,则一个磁盘块只能存放256个索引项。如果一个文件的大小超过了256块,那么一个磁盘块是装不下文件的整张索引表的。可采用链接方案、多层索引、混合索引来解决问题

    链接方案

    如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    这种设计的缺陷是若想要访问文件的最后一个逻辑块,就必须找到最后一个索引块(第256个索引块),而各个索引块之间是用指针链接起来的,因此必须先顺序地读入前255个索引块。

    多层索引

    建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。

    image-20240525082958148

    采用K层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要K + 1次读磁盘操作。

    混合索引

    多种索引分配方式的结合。

    例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。

    image-20240525083127403

    若顶级索引表还没读入内存,访问0~7号逻辑块,两次读磁盘;访问8~263,三次读磁盘;访问264~ 65799,四次读磁盘。

    对于小文件,只需较少的读磁盘次数就可以访问目标数据块。

    混合索引的计算

    image-20240525221321137

    1. 直接地址

    为了提高对小文件的检索速度,在索引节点中可设置10个直接地址项,即用iaddr(0)~iaddr(9)来存放直接地址,即文件数据块的盘块号。假如每个盘块的大小为4KB,当文件不大于40KB时,便可直接从索引节点中读出该文件的全部盘块号。

    1. 一次间接地址

    对于中、大型文件,可利用索引节点中的地址项iaddr(10)来提供一次间接地址,即采用一级索引分配。

    一次间接地址中记录了文件的一次间址块号,一次间址块就是索引块,其中记录了文件数据块的盘块号。一次间址块中可以存放1024个盘块号,可以表示1Kx4KB=4MB大小的文件。因此,同时采用直接地址和一次间址,允许的文件最大长度为4MB+40KB。

    1. 多次间接地址

    当文件长度大于4MB+40KB时,还需利用地址项iaddr(11)来提供二次间接地址,即采用两级索引分配。二次间接地址中记录了文件的主索引块号,主索引块中记录了文件的一次间址块号。当地址项iaddr(l1)作为二次间址块时,可以表示1Kx1Kx4KB=4GB大小的文件。

    因此,同时采用直接地址、一次间址和二次间址时,允许的文件最大长度为4GB+4MB+40KB。

    同理,同时采用直接地址、一次间址、二次间址和三次间址时,允许的文件最大长度为4TB+4GB+4MB+40KB。

    1. 根据多层索引、混合索引的结构计算出文件的最大长度(各级索引表最大不能超过一个块)
    2. 分析访问某个数据块所需要的读磁盘次数(FCB中会存有指向顶级索引块的指针,因此可以根据FCB读入顶级索引块。每次读入下一级的索引块都需要一次读磁盘操作)。
    3. 要注意题目条件,顶级索引块是否已调入内存。

    总结

    image-20240525083310960

    文件存储空间管理

    文件存储空间管理主要探讨对空闲磁盘块的管理。

    存储空间的划分与初始化

    image-20240525084126451

    空闲表法

    适用于“连续分配方式”。

    image-20240525084246005

    分配:与内存管理中的动态分区分配很类似,为一个文件分配连续的存储空间。同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。

    回收:与内存管理中的动态分区分配很类似,当回收某个存储区时需要有四种情况,1)回收区的前后都没有相邻空闲区;2)回收区的前后都是空闲区;3)回收区前面是空闲区;4)回收区后面是空闲区。

    空闲链表法

    空闲盘块链

    适用于离散分配(较难得到连续的空间)的物理结构。为文件分配多个盘块时可能要重复多次操作。

    image-20240525084605402

    操作系统保存着链头、链尾指针。

    分配:若某文件申请K个盘块,则从链头开始依次摘下K个盘块分配,并修改空闲链的链头指针。

    回收:回收的盘块依次挂到链尾,并修改空闲链的链尾指针。

    空闲盘区链

    离散分配、连续分配都适用。为一个文件分配多个盘块时效率更高。

    image-20240525084706010

    操作系统保存着链头、链尾指针。

    分配:若某文件申请K个盘块,则可以采用首次适应、最佳适应等算法,从链头开始检索,按照算法规则找到一个大小符合要求的空闲盘区,分配给文件。若没有合适的连续空闲块,也可以将不同盘区的盘块同时分配给一个文件,注意分配后可能要修改相应的链指针、盘区大小等数据。

    回收:若回收区和某个空闲盘区相邻,则需要将回收区合并到空闲盘区中。若回收区没有和任何空闲区相邻,将回收区作为单独的一个空闲盘区挂到链尾。

    位示图法

    连续分配、离散分配都适用。

    image-20240525085208111

    每个二进制位对应一个盘块。在本例中,“0”代表盘块空闲“1”代表盘块已分配。位示图一般用连续的“字”来表示,如本例中一个字的字长是16位,字中的每一位对应一个盘块。因此可以用(字号,位号)对应一个盘块号。当然有的题目中也描述为(行号,列号)。

    (字号,位号)=(i, j)的二进制位对应的盘块号b = ni + j

    b号盘块对应的字号i = b/n,位号j = b%n

    :注意盘块号、字号、位号到底是从0开始还是从1开始。

    分配:若文件需要K个块,1)顺序扫描位示图,找到K个相邻或不相邻的“0”;2)根据字号、位号算出对应的盘块号,将相应盘块分配给文件;3)将相应位设置为“1”。

    回收:1)根据回收的盘块号计算出对应的字号、位号;2)将相应二进制位设为“0”

    成组链接法

    空闲表法、空闲链表法不适用于大型文件系统,因为空闲表或空闲链表可能过大。UNIX系统中采用了成组链接法对磁盘空闲块进行管理。

    image-20240525085315223

    文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。

    image-20240525085409521

    分配:

    需要1个空闲块,1)检查第一个分组的块数是否足够。1<100,因此是足够的。2)分配第一个分组中的1个空闲块,并修改相应数据。

    需要100个空闲块,1)检查第一个分组的块数是否足够。100=100,是足够的。2)分配第一个分组中的100个空闲块。但是由于300号块内存放了再下一组的信息,因此300号块的数据需要复制到超级块中。

    回收:

    假设每个分组最多为100个空闲块,此时第一个分组已有100个块,还要再回收一块。需要将超级块中的数据复制到新回收的块中,并修改超级块的内容,让新回收的块成为第一个分组。

    文件的基本操作

    创建文件

    进行Create系统调用时,需要提供的几个主要参数:

    1. 所需的外存空间大小(如:一个盘块,即1KB)

    2. 文件存放路径(“D:/Demo”)

    3. 文件名(这个地方默认为“新建文本文档.txt”)

    操作系统在处理Create系统调用时,主要做了两件事:

    1. 在外存中找到文件所需的空间(空闲链表法、位示图、成组链接法等管理策略,找到空闲空间),即分配外存空间。
    2. 根据文件存放路径的信息找到该目录对应的目录文件(此处就是D:/Demo目录),在目录中创建该文件对应的目录项。目录项中包含了文件名、文件在外存中的存放位置等信息。

    删除文件

    进行Delete系统调用时,需要提供的几个主要参数:

    1. 文件存放路径(“D:/Demo”)
    2. 文件名(“test.txt”)

    操作系统在处理Delete系统调用时,主要做了几件事:

    1. 根据文件存放路径找到相应的目录文件,从目录中找到文件名对应的目录项
    2. 根据该目录项记录的文件在外存的存放位置、文件大小等信息,回收文件占用的磁盘块。(回收磁盘块时,根据空闲表法、空闲链表法、位图法等管理策略的不同,需要做不同的处理)
    3. 从目录表中删除文件对应的目录项

    打开文件

    使用open系统调用“打开文件”,需要提供的几个主要参数:

    1. 文件存放路径(“D:/Demo”)
    2. 文件名(“test.txt”)
    3. 要对文件的操作类型(如:r只读;rw读写等)

    操作系统在处理open系统调用时,主要做了几件事:

    1. 根据文件存放路径找到相应的目录文件,从目录中找到文件名对应的的目录项,并检查该用户是否有指定的操作权限。
    2. 目录项复制到内存中的“打开文件表”中。并将对应表目的编号(索引号,也即文件描述符)返回给用户。之后用户使用打开文件表的编号来指明要操作的文件

    文件名不必是打开文件表的一部分,因为一旦完成对FCB在磁盘上的定位,系统就不再使用文件名。对于访问打开文件表的索引号,UNIX称之为文件描述符,而Windows称之为文件句柄。因此,只要文件未被关闭,所有文件操作都是通过文件描述符(而不是文件名)来进行。

    :只要完成了文件打开open系统调用,后面再使用read、write、Lseek、close等文件操作的系统调用,就不再使用文件名,而使用文件描述符。

    关闭文件

    进程使用完文件后,要“关闭文件”。操作系统在处理close系统调用时,主要做了几件事:

    1. 将进程的打开文件表相应表项删除
    2. 回收分配给该文件的内存空间等资源
    3. 系统打开文件表的打开计数器count减1,若count =0,则删除对应表项。

    :关闭文件不意味着将文件数据写回磁盘,只是将文件当前的控制信息写回磁盘,写文件操作才会写回磁盘。

    读文件

    进程使用read系统调用完成写操作。需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要读入多少数据(如:读入1KB)、指明读入的数据要放在内存中的什么位置。

    主要次序:

    1. 按文件描述符在打开文件表中找到该文件的目录项
    2. 按存取控制说明检查访问的合法性
    3. 根据目录项中文件的逻辑和物理组织形式,将逻辑地址号转换成物理地址号
    4. 向设备驱动程序发出I/O请求,完成数据交换工作

    操作系统在处理read系统调用时,会从读指针指向的外存中,将用户指定大小的数据读入用户指定的内存区域中。

    写文件

    进程使用write系统调用完成写操作,需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要写出多少数据(如:写出1KB)、写回外存的数据放在内存中的什么位置。

    操作系统在处理write系统调用时,会从用户指定的内存区域中,将指定大小的数据写回写指针指向的外存。

    文件保护

    口令保护

    为文件设置一个“口令”,用户想要访问文件时需要提供口令,由系统验证口令是否正确。

    实现开销小,但”口令”一般存放在FCB或索引结点中(也就是存放在系统中)因此不太安全。

    加密保护

    用一个“密码"对文件加密,用户想要访问文件时,需要提供相同的”密码”才能正确的解密。

    安全性高,但加密/解密需要耗费一定的时间(Eg:异或加密)。

    访问控制

    用一个访问控制表(ACL)记录各个用户(或各组用户)对文件的访问权限。

    image-20240525212100672

    对文件的访问类型可以分为:读/写/执行/删除/列表清单等。

    实现灵活,可以实现复杂的文件保护功能。

    注1:如果对某个目录进行了访问权限的控制,那也要对目录下的所有文件进行相同的访问权限控制。

    注2:访问权限是文件所持有的,即某文件的访问权限表能够说明所有用户具有的所有权限情况。

    文件系统的体系结构

    image-20240525132045206

    用一个例子来辅助记忆文件系统的层次结构:

    假设某用户请求删除文件“D:/工作目录/学生信息.xlsx”的最后100条记录。

    1. 用户需要通过操作系统提供的接口发出上述请求——用户接口
    2. 由于用户提供的是文件的存放路径,因此需要操作系统一层一层地查找目录,找到对应的目录项——文件目录系统
    3. 不同的用户对文件有不同的操作权限,因此为了保证安全,需要检查用户是否有访问权限——存取控制模块(存取控制验证层)
    4. 验证了用户的访问权限之后,需要把用户提供的“记录号”转变为对应的逻辑地址——逻辑文件系统与文件信息缓冲区
    5. 知道了目标记录对应的逻辑地址后,还需要转换成实际的物理地址——物理文件系统
    6. 要删除这条记录,必定要对磁盘设备发出请求——设备管理程序模块
    7. 删除这些记录后,会有一些盘块空闲,因此要将这些空闲盘块回收——辅助分配模块

    文件系统的全局结构

    磁盘初始化

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    image-20240525132728846

    image-20240525132739192

    image-20240525132836613

    文件在外存的结构

    image-20240525132943775

    文件在内存的结构

    image-20240525133024124

    系统调用过程(open)

    image-20240525133042382

    虚拟文件系统

    普通文件系统

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    虚拟文件系统

    image-20240525133547785

    虚拟文件系统的特点:

    1. 向上层用户进程提供统一的标准的系统调用接口,屏蔽底层具体文件系统的实现差异。
    2. VFS要求要求下层文件系统必须实现某些规定的函数功能,open/read/write。一个新的文件系统想要在某操作系统上被使用,就必须满足该操作系统VFS的要求。
    3. 每打开一个文件,VFS就在主存中新建一个vnode,用统一的数据结构表示文件,无论该文件存储在哪个文件系统。打开文件后,创建vnode,并将文件信息复制到vnode中,vnode的功能指针指向具体文件系统的函数功能。

    image-20240525133911946

    :vnode只存在于主存中,而inode既会被调入主存,也会在外存中存储。

    文件系统挂载

    文件系统挂载(mounting),即文件系统安装/装载。

    文件系统挂载要做的事:

    1. 在VFS中注册新挂载的文件系统。

    内存中的挂载表(mount table)包含每个文件系统的相关信息,包括文件系统类型、容量大小等。

    1. 新挂载的文件系统,要向VFS提供一个函数地址列表。
    2. 将新文件系统加到挂载点(mount point),也就是将新文件系统挂载在某个父目录下。
  • 相关阅读:
    JavaScript基础:数据类型
    Java CountDownLatch 学习总结
    mavenj解决依赖冲突
    UE5报错及解决办法
    使用windows钩子(HOOK)实现DLL注入
    【强化学习】基础概念
    【容器】Dockerfile学习1
    国际标准ISO/IEC 30144: 2020在智能变电站辅助监测中的应用研究
    联想用万全智算,画出中国AI的山脊
    K8s的集群调度
  • 原文地址:https://blog.csdn.net/m0_61049985/article/details/139359464