我是一块硬盘

大家经常吐槽我的速度慢,说我是机械装置。但是谁没有缺点呢?况且,我持久化数据、容量大、价格低的优势,分分钟可以碾压CPU和内存老弟!今天,我想向世人介绍我自己,我相信,在我介绍完之后,大家一定能够开始理解并真正喜欢上我。

下面是我的外表,一块金属片,和一些机械装置。今天,我的容量已经可以达到1TB甚至1PB的大小,在计算机中起到了举足轻重的作用!

我是一块硬盘

而我的内部也非常丰富!我的内部由一个主轴串着许多盘片,就像冰糖葫芦一样,每个盘片的上下面都是用来存储数据的,由两个读写磁头在盘面上移动、旋转,来读写数据。看起来像不像老式的转唱机?

对于每一个盘面,有一些同心圆环,叫做磁道,把一个给定磁盘臂位置的所有磁盘的对应磁道合并起来,组成了一个柱面。每个磁道划分为若干扇区。在我工作的时候,主轴带动所有的盘片高速旋转,读写磁头负责前进后退,首先找到对应的磁道(花的时间叫做寻道延迟),再找到对应的扇区(花的时间叫旋转延迟),再对特定扇区进行数据的读写操作,数据读写的过程是电磁变化的过程。到这里,大家应该能理解为啥我那么慢了,因为我要机械地移动和旋转,拿我和CPU比速度,那比就是拿自行车跟飞机比谁更快么!

我是一块硬盘

文件的实现

但在实际使用时,大家是不知道我的具体细节的,也不需要关心要在我的哪个盘片、哪个磁道、哪个扇区去读取数据。因为我给了人们一个叫做磁盘块的存储单元。你只需要说,我要第xx磁盘块,得勒,我就能告诉你它在哪。

一、连续分配

用块作为逻辑的存储单位,是为了存储文件!没错,你们日常使用的文件,其在磁盘的基本单位就是块。那么,多个磁盘块是如何组成一个文件的呢?最简单的方法,就是连续分配。将连续的磁盘块用来存储文件的内容。非常简单吧?而且只需要第一个块的位置0,可以访问第n块的内容,因为它们是连续的!

我是一块硬盘

二、链表分配

但是会有一个磁盘碎片的问题,比如文件B被删除了,但是它所在的3个磁盘块会被空着,这就是磁盘碎片。怎么利用这3个磁盘块呢?天啊,要么将后面的文件C的内容往前移,要么往碎片中填充新的内容。第一种要复制内容到前面,太浪费时间了,第二种又不知道放什么内容好。啊,碎片真的让我头大。所以,还有其它的存储文件的方法:链表分配。

我是一块硬盘

简单来说,每个块可以不是连续的,在文件块的头几个字节作为一个指针,指向下一个存储的文件块。这就解决了磁盘碎片的问题了,有木有!但是这种方法有两个缺点,一个是每个块都将有指针,这浪费了空间;二是不能再愉快的访问任意个文件块了,比如要访问文件块4,那我必须先依次访问文件块0、1、2、3,这浪费了时间。

三、采用内存中的表进行链表分配

为了解决链表分配的问题,我把这个指针放在内存里,这就是第三个方案:采用内存中的表进行链表分配。

我是一块硬盘

上面这张指针地址表放在内存中,解决了占用磁盘空间的问题,要想访问任意一块,现在内存计算好最终的地址,再去访问磁盘,这样就不需要在磁盘上浪费宝贵的时间了。我们将内存中这样一张表叫做:文件分配表。当然,缺点也有,就是这张表记录了所有的磁盘块,所以当磁盘容量太大的时候,就GG了,因为这张表就会在内存占用太大的空间,这可不是一件好事!

四、i节点
当前大部分Linux操作系统采用的是i节点的文件存储方案。在这个方案中,每个文件都会被赋予叫做一个i节点的数据结构,其中列出了文件属性和文件块的磁盘地址。只要给定i节点,就能找到对应的文件块!而且只有文件打开时,其对应的i节点才会在内存中出现。也不需要在内存维护一个那么长的表了。i节点实现文件存储是当前比较流行的实现。

说了那么多,我都有点口渴了呢。大家要不改天再聊?下次可以去教室找我,我有一个弟弟:内存。到时我再向各位介绍他。感谢大家的时间,下次再见啦!

欢迎关注我的公众号:小谢backup
我是一块硬盘