Filesystems 为什么Windows使用FAT结构而不是传统的链表,每个数据块都有下一个指针?

Filesystems 为什么Windows使用FAT结构而不是传统的链表,每个数据块都有下一个指针?,filesystems,fat,Filesystems,Fat,与其将对下一个节点的引用存储在表中,为什么不能像传统的链表一样存储,即使用下一个指针呢?任何现代操作系统都需要的不仅仅是指向其文件系统下一个数据块的指针:属性(加密、压缩、隐藏等)、安全描述符(ACL列表项),支持不同的硬件、缓冲。这只是任何好的文件系统所具有功能的一小部分 看看维基百科,了解现代文件系统的其他功能。这是由于对齐。(以及几乎任何其他文件系统)将文件数据存储在底层存储的一个或多个完整扇区中。因为底层存储只能读写整个扇区,所以这种分配允许高效地访问文件内容 交织问题 当程序想要在文件

与其将对下一个节点的引用存储在表中,为什么不能像传统的链表一样存储,即使用下一个指针呢?

任何现代操作系统都需要的不仅仅是指向其文件系统下一个数据块的指针:属性(加密、压缩、隐藏等)、安全描述符(ACL列表项),支持不同的硬件、缓冲。这只是任何好的文件系统所具有功能的一小部分

看看维基百科,了解现代文件系统的其他功能。

这是由于对齐。(以及几乎任何其他文件系统)将文件数据存储在底层存储的一个或多个完整扇区中。因为底层存储只能读写整个扇区,所以这种分配允许高效地访问文件内容

交织问题 当程序想要在文件中存储某些内容时,它会提供一个缓冲区,比如说1MB的数据来存储。现在,如果文件的数据扇区也必须保留指向其下一扇区的
next
指针,那么该指针信息将需要与实际用户数据交错。因此,文件系统需要构建另一个缓冲区(略大于提供的1MB),为每个输出扇区复制一些用户数据和相应的
next
指针,并将此新缓冲区提供给存储器。这会有点低效。除非文件系统总是将文件数据存储到新扇区(大多数情况下不存储),否则重写这些
next
指针也是多余的

更大的问题是在尝试对文件执行读取操作时。文件现在将像磁带设备一样工作:由于文件的主要元数据中只知道第一个扇区的位置,为了达到扇区1000,文件系统需要按顺序读取它之前的所有扇区:读取扇区0,从加载的
下一个
指针中查找扇区1的地址,读取扇区1,等。对于每个随机I/O的典型寻道时间约为10 ms(假设为硬盘驱动器),到达扇区1000大约需要10秒。即使扇区是按顺序排列的,当文件系统驱动程序处理扇区N的数据时,磁头也会飞过下一个扇区,当发出扇区N+1的读取命令时,可能已经太迟了,需要磁盘旋转整圈(对于7200 RPM的驱动器为8.3毫秒),然后才能再次读取下一个扇区。不过,磁盘缓存可以而且将有助于实现这一点

写入单个扇区通常是原子操作(取决于硬件):断电后读回扇区将返回其旧内容或不带中间状态的新内容。数据库应用程序通常需要知道哪些写入是原子的。如果文件系统在相同扇区中交错文件数据和元数据,则需要向应用程序报告小于实际扇区大小的数据。例如,它可能需要报告504,而不是512字节。但它不能做到这一点,因为应用程序通常假定扇区大小为2的幂。此外,如果将存储在此类文件系统上的文件复制到另一个具有不同报告扇区大小的文件系统,则很可能无法使用

更好的方法 FAT格式更好,因为所有
next
指针都存储在相邻的扇区中。对于FAT12、FAT16和不太大的FAT32卷,整个表足够小,可以装入内存。FAT仍然将文件的块记录在一个链表中,因此为了有效地进行随机访问,实现需要缓存每个文件的链。在足够大的卷(可以运动足够大的文件)上,这样的缓存可能不再适合内存

使用。这种简单的格式避免了FAT所需的预处理,当需要间接块时,每个I/O只需要最少的额外读取。这些额外的读取由操作系统缓存,因此它们的开销通常可以忽略不计

其他变体也是可能的,可由各种文件系统使用

随机音符 为了完整性起见,一些硬盘驱动器可以格式化为略大的扇区大小(例如520字节),以便文件系统可以在同一扇区中打包512字节的文件数据和若干字节的元数据。但是由于上述原因,我认为没有人使用这种格式来存储文件下一个扇区的地址。这些额外的字节可以更好地使用:额外的校验和和时间戳出现在脑海中。我认为时间戳用于提高某些RAID系统的性能。然而,这种用法很少见,而且大多数软件根本无法使用它们


一些文件系统可以将足够小的文件的内容直接保存在文件元数据中,而不占用不同的扇区。有争议。这一点在这里并不重要:大文件仍然受益于与存储扇区的正确映射。

即使在3年前被问到,我发现这个问题很有趣。如果我们忽略FAT12在两个项目之间共享一个字节以将12位压缩为1.5字节的细节,那么我们可以集中精力讨论问题的深层含义

事实证明,FAT系统相当于具有以下几点的链表: 1-“下一个”指针位于数组(FAT)中,而不是附加或前置到实际数据中 2-写入“next”的值是一个整数,而不是下一个节点更熟悉的内存地址。 3-节点不是动态保留的,而是由另一个数组表示。该阵列是硬盘驱动器的整个数据部分

作为软件工程师教育的一部分,我们进行了一项有趣的练习,将使用内存指针的应用程序转换为使用整数值的等效应用程序。基本原理是某些处理器(PDP-11?或另一个PDP-xx)将