25.从生磁盘到文件

【README】

1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;

2.文件:煮熟的磁盘,或熟磁盘

  • 本节的主要内容是讨论 如何从文件得到盘块号

3.磁盘操作抽象(复习)

  • 第1层抽象:通过盘块号读写磁盘(或逻辑盘块号);参见 第24讲 内容;
  • 第2层抽象:用队列缓存多个进程读写的盘块号;参见 第24讲 内容;
  • 第3层抽象:文件(或通过文件操作磁盘); 参见 第25讲 内容;

4.字符流到盘块的映射

  • 顺序结构的文件存储方式;
  • 链式结构的文件存储方式;
  • 索引结构的文件存储方式;

【1】对磁盘使用的第3层抽象-文件

1)为什么引入文件 ?

 【图解】
1)用户眼里的文件: 字符序列 或 字符流;
2)磁盘上的文件:文件内容分散存储在多个相邻盘块(逻辑),或多个相邻扇区(物理);
3)文件:

  • 建立字符流到盘块集合的映射关系,或字符流到扇区集合的映射关系;
  • 使用映射关系就可以把文件计算出盘块号;

【2】字符流到盘块号的映射

1)操作系统负责维护这个映射关系(字符流到盘块号的映射关系);

 【图解】
1)映射例子: test.c文件中的 200~212 字符对应盘块为 789;如 上层用户程序命令是把 200~212 的字符删除掉;

  • 操作系统会解释这个文件字符删除命令,查找200~212对应的盘块号;
  • 拿到盘块去创建一个磁盘读写请求,并放入请求队列;
  • 磁盘控制器在完成上一个盘块的读写后,发出中断;
  • 中断处理程序会发出命令让磁盘控制器使用电梯算法选择下一个盘块进行读写;

【2.1】连续(顺序)结构的文件存储方式

1)连续结构:

  • 文件内容顺序存放在相邻盘块 ;

2)根据字符流如何计算出盘块号(非常重要*)

  • 如 test.c 第0~99字符流放在盘块6;第100~199放在盘块7;第200~299放在盘块8;那所以200~212映射到盘块8。
  • 计算逻辑也可以是  200/100 = 2;盘块偏移量是2,初始盘块号为6,所以目标盘块号是 6+2=8;

3)文件控制块结构体 FCB-file controll block
FCB就是inode;

文件名

起始块

块数

test.c

6

3

4)连续结构的文件存储方式的问题

  • 当test.c的内容不断增加,其所用盘块也会连续增加,增加到第14块(上图黄色标识)的时候,
  • 而第14块原本是被 test2.c 占用的,为了 保证test.c文件的连续性,需要把test2.c 文件内容挪到其他地方,这就影响了文件读写的性能

总结:连续结构的文件存储方式,适合读写,但不适合文件内容动态增长


【2.2】链式结构的文件存储方式

【图解】
1)FCB 结构中的起始块是1;
2) 链表结构:

  • test.c文件分散存储在 盘块10,盘块17,盘块9;3个盘块分别存储了 0~99,100~199,200~299 范围的字符;

3) 链表结构扫描方式:

  • 所以要把 200~212范围的字符删除掉,由于是链表结构,磁盘控制器需要把盘块10,盘块17,盘块9依次读入内存,最终在盘块9中做操作;因为 盘块10的next指针指向盘块17,盘块17的next指针指向盘块9,盘块9的next指针为null, 所以需要依次读入链表上的盘块(链表的缺点)

总计:链式结构的文件存储方式

  • 优点:适合动态增长;
  • 缺点:读写性能慢,因为要从头开始扫描盘块号;

【2.3】索引结构的文件存储方式

1)关于inode:文件信息数据结构inode 中的 i 就是指的是 index索引,而node指的是 文件控制块FCB
2)索引: 索引就是目录;

 【图解】基于索引结构的文件存储方式访问磁盘步骤

  • 1)步骤1:读入文件 test.c 的 inode 即 FCB;
  • 2)步骤2:从FCB找到索引块19,说明盘块19 存储了文件内容的盘块索引(存储了字符流与盘块映射关系),则读入盘块19中的所有内容(如下表);
  • 3)步骤3:计算盘块号。

索引块19存储的索引如下:

逻辑序号

盘块号

存储字符范围

0

9

0~99

1

17

100~199

2

1

200~299

3

10

300~399

4

-1(null)

所以要操作 200~212范围的字符,只需要用 200/100 = 2,获取下标2的盘块,即盘块1;

【总结】索引结构总结(重要 *)

  • 适合顺序读写,因为索引是一个数组,带有连续下标;
  • 也适合动态增长,因为多个索引项是分散的,不是连续的(但逻辑下标是连续的);
  • (特别重要*)所有的linux, unix的文件系统使用的都是索引结构对字符流到盘块的映射

  • 【3】多级索引

【图解】
1)小文件inode的索引块直接指向数据块

  • 即inode结构体中的索引块就是数据块,如 ptr1, ptr2, ptr3 等(如黄色部分);

2)中等文件inode 使用一阶间接索引

  • 即 inode结构体中的索引块就是索引块,存储了文件内容使用的多个分散盘块号(分散盘块号的逻辑序号是连续的),如下表,盘块号9,17,1,10是分散的,但逻辑序号(下标)是连续的:

逻辑序号

盘块号

存储字符范围

0

9

0~99

1

17

100~199

2

1

200~299

3

10

300~399

4

-1(null)

 然后再根据要操作的字符范围算出逻辑序号,进而找到盘块号,把盘块号封装到文件请求送入请求队列即可。

3)大型文件inode使用二阶或三阶间接索引

  • 原理与一阶间接索引类似;

总结:多级索引(非常重要*)

  • 使用三阶间接索引可以表示非常大的文件;
  • 很小的文件(小文件)直接指向数据块,因此高效访问;
  • 中等文件采用一阶间接索引,也不慢;


【小结】

  • 1)如何从生磁盘抽象为文件?
  • 核心是从字符流位置算出盘块号;

2)如何算出盘块号?

  • 用到顺序结构,或链式结构,或索引结构提供的映射表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Storm 1.0.1发布 .NET 适配也已到来

Apache Storm 1.0.0刚发布不久,1.0.1版本也在几天前到来;该版本主要是完成一些BUG修复和小的改进,通过一段时间新版本的使用,特将个人感受和一些遇到的问题归纳如下;另外 .NET 版本的 Storm 适配器也已经发布&#xff…

布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项

今天碰到个业务,他的 Redis 集群有个大 Value 用途是作为布隆过滤器,但沟通的时候被小怼了一下,意思大概是 “布隆过滤器原理都不懂,还要我优化?”。技术菜被人怼认了、怪不得别人,自己之前确实只是听说过这…

Oracle入门(十四)之PL/SQL

一、PL/SQL 基本语法 PL/SQL语言是模块式的过程化SQL,是oracle公司对SQL的扩展。 (1)(2)(3)(5)(6)(7)数据类型Number 数字型Varchar2 …

26.文件使用磁盘的代码实现

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐; 2.文件内容复习: 1)如何从生磁盘抽象为文件? 核心是从字符流位置算出盘块号;2)如何算出盘…

.NET Core全新的配置管理[共9篇]

提到“配置”二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置信息定义在这两个文件之中。到了.NET Core的时候,很多我们…

redis存opc_KEPServerEX6完整免费版

KEPServerEX6完整免费版是一款先进的连接平台,主要用于为您的应用程序提供单一来源的工业自动化数据,通过连接、管理、监视和控制不通的自动化设备和应用程序来实现工业数据。具有严谨的技术特征,支持多达250种以上的通讯协定,可连…

Oracle入门(十四B)之PL/SQL异常处理

定义:程序执行过程的警告或错误成为例外(Exception) 一、常见预定义错误 二、非预定义错误及用户定义错误 (1)非预定义oracle错误其他标准的oracle错误,可以自定义异常名,将其与指定oracle错误关联,由系统触发。 例子…

C#读书雷达 | TW洞见

大家都知道,ThoughtWorks的技术雷达每年都会发布两到三次,它不但是业界技术趋势的标杆,更提供了一种卓有成效的方法论,即打造自己的技术雷达。在这种思想的驱动下,我们诞生了自己的读书雷达。但这份雷达略显high level…

27.目录与文件系统

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐; 2.第4层抽象:抽象整个磁盘到文件系统 【1】文件系统,抽象整个磁盘(第4层抽象) 【图解】整个磁盘抽象1…

dd命令打包多个文件_linux的tar命令详情;linux多个文件压缩打包到一个压缩文件...

tar命令可以用来压缩打包单文件、多个文件、单个目录、多个目录。Linux打包命令_tartar命令可以用来压缩打包单文件、多个文件、单个目录、多个目录。常用格式:单个文件压缩打包 tar czvf my.tar.gz file1多个文件压缩打包 tar czvf my.tar.gz file1 file2,...(file…

28.文件目录解析代码实现

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐; 背景: 磁盘格式化后,其组成部分包括引导块,超级块,inode使用位图,盘块使用位图&#xff0…

Oracle入门(十四A)之PL/SQL 基本结构

一、条件控制语句 &#xff08;1&#xff09;条件语句Iif…then…end if形式1:if <布尔表达式> then…(pl/sql和sql)…end if;&#xff08;2&#xff09;条件语句II if…then…else … end if 形式2&#xff1a;if <布尔表达式> then…(pl/sql和sql)else…end if;…

利用记事本创建一个ASP.NET Core RC2 MVC应用

步骤一、安装最新的.NET Core SDK 我们可以根据自身的操作系统环境从https://github.com/dotnet/cli上下载.NET Core最新的SDK&#xff0c;这个SDK包含.NET Core Runtime和一些有用工具&#xff08;比如命令行&#xff09;。如果你已经安装了老旧的版本&#xff0c;我个人建议你…

datatable中某一列最小值_获取DataTable 某一列所有值

//获取某一列值string orderids (from d in dt.AsEnumerable() select d.Field("OrderID")).ToList().ListToString();/// /// 判断字符串是否在某字符串数组当中/// /// /// /// public static bool In(this string value, params string[] items){return items.An…

29.操作系统对磁盘的4层抽象小结

【README】 本文总结了操作系统 对磁盘的4层抽象&#xff0c;并给出了详细介绍的post 链接&#xff1b; 【1】对磁盘的4层抽象 【1.1】对磁盘的第1层抽象 通过盘块号读写磁盘&#xff08;读写多个扇区&#xff09;&#xff1b; 因为磁盘底层操作的单位是扇区&#xff08;51…

Oracle入门(十四C)之转换函数

一、数据转换类型 为数据库创建表时&#xff0c;SQL 程序员必须定义在表的各个字段中存储何种数据。在 SQL 中&#xff0c;有几种不同的数据类型。这些数据类型用于定义每个列中可以包含的值的范围。 &#xff08;1&#xff09;在本文中将使用以下数据类型VARCHAR2 CHAR NUMBER…

发布在即!.NET Core 1.0 RC2已准备就绪

先说点废话&#xff0c;从去年夏天就开始关注学习ASP.NET Core&#xff0c;那时候的版本还是beta5&#xff0c;断断续续不停踩坑、一路研究到11月份RC1发布。 在这个乐此不疲的过程里&#xff0c;学习了很多新的东西&#xff0c;对ASP.NET Core也是越来越喜爱。然而到现在&…

1.java IO模型(BIO,NIO,AIO)

【README】 本文介绍了 3种 java io模型&#xff0c;包括 BIO&#xff0c;NIO&#xff0c; AIO&#xff1b; IO模型名称 描述 工作原理 BIO-Blocking IO 同步并阻塞式IO 一个服务器线程处理一个客户端连接 NIO-Non-blocking IO 同步非阻塞式IO 一个服务器线程处理多个…

Oracle入门(十四D)之常规函数

一、NULL处理 &#xff08;1&#xff09;函数的计算过程 到目前为止&#xff0c;您已经学会了在简单语句中应用单行函数。不过&#xff0c;函数可以嵌套任意层。所以&#xff0c;了解嵌套函数的计算过程非常重要。下例就是一个嵌套函数。其计算过程是从最里层开始计算&#xff…

python定义函数prime判断是否是素数_用自定义函数判断素数 用C语言编写自定义函数prime(int x),判断x是否为素数?...

用C语言编写自定义函数prime(int x)&#xff0c;判断x是否为素数&#xff1f;int prime(int x){int i&#xff0c;kk(int)sqrt( (double)x )for(i2i&ltki )if(x%i0)break// 如果完成所有循环&#xff0c;那么x为素数if(i&gtk)retrun 1elsereturn 0}C语言&#xff0c;编…