文件的存储(磁盘的物理和逻辑结构)

个人主页:小则又沐风

个人专栏:<数据结构>

<竞赛专栏>

<C语言>
<C++>

<Linux>

座右铭

路虽远,行则将至;事虽难,做则必成

前言

在上一篇的文章中我们了解了与文件相关的操作,简单的了解了进程时怎么打开文件的,但是文件是存储在那里的呢?

我们在日常的认识中就知道了我们的文件是存储在我们的硬盘中的,但是真正的存储的方式是什么我们并不知道,现在我们来了解一下文件系统

磁盘

磁盘的物理结构

磁盘是家喻户晓的硬件,但是他的内部结构是什么我们并不知道,现在我们就来仔细地去了解一下

上面是磁盘的实物图,我们可以直接的看出来磁盘的主要的结构

下面来看磁盘的物理结构示意图

我们看上述图片中的染色部分,这个就是磁盘存储信息的单位结构,称作为扇区

一般的来说,一个扇区可以存储的字节大小是512字节,一个一个扇区组成的一个个的环状结构我们称为磁道,一个个磁道组成了一个面,这个面就是盘面

然后我们的信息就是这样的存储在磁盘中的,现在应该怎么读取磁盘中的数据呢?

磁头就可以来通过在盘面上的移动来实现对指定位置扇区中数据的读取了

从第二张的图片中我们得到的信息是一个盘是有两个面的两个面都可以存储信息,所以一个盘是有两个磁头的,主轴上不仅仅是有一个盘的

从这个图中我们可以知道的是磁头是由一个机械臂控制的,所以这一个个的磁头的运动是同步的,他们是共进退的,那么这些磁头指向的扇区构成的结构叫做柱面

现在我们简单的了解了磁盘的结构

知道了数据是以扇区的结构存储在磁盘上的.

如何定位扇区

既然知道了数据的存储是在扇区上存储的,但是一个盘片中的数据就有那么多了

现在出现了新的问题了,怎么正确的读取正确的扇区呢?

CHS地址定位

CHS地址定位的方法就是

首先我们让机械臂将磁头移动到我们想要访问的柱面的位置

然后确定具体的磁头来确定到扇面

现在来补充一条知识

计算一个磁盘的容量

首先我们想要计算一个磁盘的容量我们需要知道的是磁盘的组成

磁盘的存储的单位是扇区,一个磁道中含有多个扇区,

所以磁道数*一个磁道扇区的个数*一个扇区的字节大小

上面就是一个盘面的容量

但是磁盘不仅仅是一个盘面

一个盘面就会有一个磁头

所以最终的计算的公式就是

磁头数*磁道数*一个磁道扇区的个数*一个扇区的字节大小

磁盘的逻辑结构

在上面我们简单的了解了磁盘的物理结构

下面将会了解磁盘的逻辑结构

想必大家都见过这种的磁盘把?

如果我们把这个磁盘的磁带全部抽出来的话,我们将会得到一个长长的磁带了,我们就把这个磁带从一个一圈圈的圆环拉直了.

那么我们把这个拉直之后的磁带看作一个一维数组的话,就会得到下面的一张图片

是不是意味着我们的磁盘是可以抽象一个数组的

如果一个个的数组代表的是一个个的扇区的话.就相当于我们把一个磁道拉直了,

所以我们可以把一个盘面中的一个磁道看作一个一维数组

这样的话,一个个的扇区会因为数组这个结构拥有一个下标了,

这样每⼀个扇区,就有了⼀个线性地址(其实就是数组下标),这种地址叫做 LBA

但是实际上的磁盘并不是这样简单的结构

磁盘中有很多的盘面

那么实际上在逻辑上是怎么进行的编址的呢?

在上述的讲解中,我们提到过一嘴的是磁头是依靠机械臂来实现移动的,所以这就造成了磁头会共进退的,所以他们会处于一个相同半径的圆环中,这一个个的圆环构成了一个柱面

现在我们单独的看这个柱面,我们现在用剪刀把这个柱面剪开的话,我们得到的就是不同盘面,相同磁道拉之后的东西

圆柱的侧面展开图是一个长方形

一个柱面的展开就可以得到一个这样的结构

这个就很容易想到的就是二维数组了

所以我们就可以这样的理解柱面就是一个二维数组

磁盘就是一个个的二维数组构成的

抽象的可以看作这个图片

现在我们的认识就刷新了,磁盘就是一个个的二维数组构成的

在我们之前的学习中,我们知道的是无论是几维数组,我们都可以看作是一个一维数组的

上面的图就是具体的线性地址

但是我们怎么得到LBA地址呢?

我们就来用一个例子来解释这个问题把

首先假设我们处于第二个柱面中的第二个磁头的第二个的第二个扇区中

我们需要知道的就是这个LBA就是我们抽象出来数组的下标,那么他是从小到大来分配的

那么知道了在我们目标扇区之前有多少个扇区就可以计算出目标扇区LBA地址了

因为现在是位于第二个柱面上的,所以第一个柱面一定是被占用的了,所以目标扇区之前的柱面个数*每个柱面包含扇区的个数,计算的是之前柱面包含的扇区

下面就是计算当前柱面的扇区了

目标扇区是位于第二个磁头的那么,之前的磁头一定也是被占用的了,所以目标扇区之前的磁头个数*每个磁道包含的扇区个数

现在我们解决了目标扇区之前的柱面和磁道所包含的扇区了,现在就是计算当前磁道中目标扇区之前的扇区了

所以综合的计算公式就是

柱面个数*每个柱面包含扇区的个数+磁头个数*每个磁道包含的扇区个数+当前磁道中目标扇区之前的扇区

但是需要主要的是在我们的数组中我们一般是从下标0开始计数的,但是实际的硬件个数是从1开始的

上述我们讲解的是怎么将CHS转换为LBA地址

将LBA地址转化为CHS地址

因为上述的公式的存在,所以就是一个简单的逆运算

柱⾯号C=LBA//(磁头数*每磁道扇区数)【就是单个柱⾯的扇区总数】

• 磁头号H=(LBA%(磁头数*每磁道扇区数))//每磁道扇区数

• 扇区号S=LBA%每磁道扇区数)+1

• "//":表⽰除取整

在日常的使用的时候我们其实并不关心什么CHS地址

我们使用的是LBA地址,这个地址他会自动用上述的算法转化为CHS地址的