文件系统是操作系统中用于管理存储设备上的分区和文件的方法和数据结构。随着存储设备的升级发展,与其相应的文件系统也在不停地发展。
常用的存储设备有TF卡,U盘,硬盘(包括机械硬盘和固态硬盘)。存储设备接入电脑,操作系统会询问此设备是什么设备,设备会告诉系统自己是磁盘(Disk)设备,并告诉操作系统设备名称,类型等存储设备信息。然后操作系统就会将设备显示在系统中,如下图红框中。
磁盘被接入系统中后,系统显示磁盘驱动器,并且为每个磁盘分配磁盘驱动器号,也被称为物理驱动号(Physical Driver No),如下图中的0,1,2,3,4。
物理盘还没有文件系统,访问非常不方便。磁盘设备经过操作系统的文件系统驱动之后,磁盘就被划分为一个或多个逻辑盘,逻辑盘是用卷来标识,卷名示例:_ _\?\Volume{cad4ebea-0000-0000-0000-c0de04000000}\。每个磁盘对应一个唯一的卷名,但是通过卷名访问设备比较麻烦。操作系统为卷提供一个别名,称为挂载点,也被称为盘符,如D:\,E:\。盘符使用方便,但是不好记忆,所以操作系统又为卷提名了一个标识,被称为卷标,如下图的Docs,Works。
FAT(File Allocation Table),是一种由微软发明并拥有部分专利的文件系统。
如上图所示,FAT文件系统分为5个主要区域,分别是引导程序区,FAT1,FAT2,目录文件项和文件数据。其中FAT1和FAT2也就是文件分配表(File Allocate Table),它是FAT文件系统的核心,用于描述磁盘空间的使用情况。引导程序区,主要包括MBR和DBR,MBR是主导分区和设置启动代码的,MBR不是必须的。
DBR,磁盘引导区,主要记录FAT1,FAT2,目录文件项,文件数据的位置,FAT表项的个数,簇大小,以及整个磁盘的可用扇区大小。
Sector,扇区,扇区大小为512的倍数,是最小的管理单元。
Cluster,簇,簇大小可以为1,2,4,8,16,32,64扇区,簇号从0开始,一个一个描述整个文件数据区。簇0,1,2,3保留,记录文件系统的一些隐藏信息。因为文件内容的最小单位为簇,所以哪怕存储一个1Byte的文件,其也会占用一个簇,如果簇大小为4K,则已用空间则会增加4K。(因为前4上簇为系统占用了,空盘也会占用16K)。
FAT2是FAT1的备份,可以有,也可以无。FAT中存储的是簇号,对应文件数据区的簇号。FAT12协议要求每12bit记录一个簇号,FAT16协议要求每16bit记录一个簇号,FAT32协议要求每32bit记录一个簇号。
目录文件项,则是记录文件目录及文件信息,标记其FAT表项有哪些,簇0上描述目录文件项。因为目录文件项大小只有一个簇大小,所以FAT的文件夹包括文件数据有限制。
通过文件系统获取文件夹及其中文件,操作系统先找到DBR,通过DBR找到目录文件项中的文件目录名,然后其中记录了FAT项号,然后找到FAT表,找到FAT项号上记录上的簇号,就可以找到文件夹的内容,文件夹内容即记录其中的文件信息(文件信息包括文件名以及文件对应的FAT表项),然后再通过文件对应的FAT表项找到相应的簇号,再通过簇号就可以找到文件数据区中的数据。
计算机早期,使用软盘存储数据,软盘的空间非常小,所以当时的文件系统主要是针对小容易的磁盘设计的。FAT12因为12bit的FAT表项大小,所最大只能记录4096个簇号,所以描述的最大容易较小。
FAT16由16bit描述FAT表项大小,最大可以描述65536个表项,最大可以支持2GB容量。FAT16也简称为FAT。
随着磁盘容量的快速增加,2GB容量很快就不够用了,然后就产生了FAT32。FAT32的文件信息项中有一项记录文件大小,FAT32标准将文件大小设置为4BYTE,4BYTE最大只能表示4GB,也即FAT32最大只能描述4GB大小的文件。FAT32有32bit描述FAT表项,簇最大小64K,32bit最多描述232 个簇,理论上FAT32可以支持非常大的容量。不过容量过大时,FAT表项非常大,这样搜索文件时效率很低,所以FAT32一般针对32GB容量以下的存储设备。
看上图,U盘内已经没有文件了,但是通过WinHex(可以直接查看物理设备内容,不经过文件系统),可以看到之前的文件还在,甚至其内容也在。这是因为文件系统删除文件,并不是完全将数据抹除,而只是将目录项中及对应的FAT表项给删除。如果接下来继续写文件,就会覆盖之前的数据内容。其实也就是说,文件删除了,只要没有覆盖写,还是可以修复回来的。
我们右键格式化U盘时,可以勾选是否快速格式化,快速格式化只是清理目标文件项区以及FAT表项,并不清理真实的文件内容,所以速度较快。如果不勾选,则会全盘格式化,会完整删除文件内容。
因为FAT最大只支持4GB文件,并且FAT表项区过大,簇过小,一则占用空间,二则搜索文件速度慢。所以为了解决上述问题,微软在FAT的基础上,开发一种新的文件系统exFAT。其分配单元大小(即簇大小)最大可以到32768kb,颗粒度大,这样搜索的速度会更快,当然小缺点是一个小文件最少也得占有一个簇大小。所以针对文件系统选择合适的簇大小非常重要,可以兼顾少浪费容量和访问速度。另外,exFAT的文件大小也采用了8BYTE描述,基本可以描述任意大小的文件。
FAT文件系统的访问性能比较差,并且在加密安全性,恢复性上功能不够,所以微软后来又开始了一个新的文件系统NTFS。NTFS(New Technology File System)是Windows NT内核的系列操作系统支持的、一个特别为网络和磁盘配额、文件加密等管理安全特性设计的磁盘格式,提供长文件名、数据保护和恢复,能通过目录和文件许可实现安全性,并支持跨越分区。
NTFS是一个日志文件系统,这意味着除了向磁盘中写入信息,该文件系统还会为所发生的所有改变保留一份日志。这一功能让NTFS文件系统在发生错误的时候(比如系统崩溃或电源供应中断)更容易恢复,也让这一系统更加强壮。在这些情况下,NTFS能够很快恢复正常,而且不会丢失任何数据。比如写一个文件,开始写的时候,日志标记开始写,写完了,日志标记完成。如果写的过程中断电,那么在重新启动后,系统会检测日志记录,发现某个文件未写完成,那么文件相关信息就会被全部废除,避免记录破损文件。
想要描述更大容量的磁盘,就必须更多表项,但是表项过多,又影响访问效率。如果增加簇大小,那么小文件占有空间太多,浪费空间。针对这种FAT的缺点,NTFS的簇设定为512-2048KB大小,一般默认为4KB,这样小文件也浪费空间少,针对FAT表项过多访问效率低,NTFS修改了通过key-value的HashTable的方式来直接找到文件对应的簇,这样效率更高。
NTFS允许长达255个字符的文件名,支持长文件名,FAT文件长文件名有一些缺陷。
F2FS 全称为 Flash Friendly File System,是一种较为新型的支持 Linux 内核使用的文件系统。最早是由三星在2012年研发设计的,其目的就是为了更好的适应 NAND 一类的闪存设备(例如固态硬盘、eMMC和SD卡等),在 F2FS 中三星应用了日志结构档案系统的概念,使它更适合用于储存设备。F2FS早期主要由三星公司赞助的人维护,后来三星放弃了此持续支持此开源项目,华为接手赞助相关项目,招募了许多三星的相关开发人员。
华为早年宣称EMMC优化达到UFS的性,所做的工作主要就是基于F2FS的优化。
系统所在的存储设备,因为系统在不停地的工作,所以会不停地读写设备,导致存储许多小文件。而F2FS文件系统可以深度与存储设备的硬件算法做配合,提升小文件的读写性能。Nand Flash有一些特性,如一次必须擦除一个块,写之前必须先擦除,而写最少写一个页。
假如某Flash的PageSize=8KB,文件系统的簇大小也为8KB。如果文件系统没有按8K对齐,那么写一个8K文件,可能就会跨2个PageSize。那么接下来所有文件都多会跨Flash的Page,这会导致性能降低。所以,所有针对NandFlash的存储设备,都要设置一下8K对齐,这样可以提升速度,尤其是写小文件的速度。像SSD的一些格式化时一般也会提升8K对齐。
EXT3是第三代扩展文件系统(Third extended filesystem,缩写为ext3),是一个日志文件系统,常用于Linux操作系统。
ext3:16TB文件系统和最大2TB文件,可能在某些特殊情况下不够用,所以继续出现了ext4,1EB文件系统和最大16TB文件。
前面有讲过,删除文件对操作系统来讲,只是清除目录项,并不会清除真正的内容。这样当操作系统进行一次1MB文件的写之后,又删除了这个文件,然后再写入1MB文件。那么在Nand Flash这边,一个块4096个页,每个页16KB,那么一个块就是8MB。Nand Flash擦除,然后写1MB的文件,操作系统删除文件,Nand Flash这边不知道,操作系统继续写1MB文件,Nand Flash这边需要先把之前写入的1MB文件读出到缓存中,再合并最新的1MB数据一起写入Nand Flash。正因为Nand Flash不知道操作系统这边的删除操作,导致Nand Flash多做了无效工作。当然这里只是简单举例说明可能存在的情况,存储设备管理算法会比这复杂,但是基本原因也是这样,只不过场景不是这样。
针对这种情况,存储设备协议,如USB存储设备,SATA存储设备,NVMe存储设备都增加了一个Trim指令。操作系统在删除文件后,会通知Nand Flash管理器,哪些区域的数据已经无效了,你不用再保留旧数据了。
MBR和GTP都是文件系统最开始的一个区域,其主要作用为引导代码和分区。引导代码是告诉Bios/UEFI我的操作系统放在哪里,有多大,启动位置在哪里等等。
如下图是MBR,其中0-1B8为引导代码,引导系统的,如果不需要引导系统,可以不用管些区域。因为MBR只512大小,而一个分区表项(Partition Table Entry)占用12Byte,除去引导代码外,剩余的空间最大只能放4个分区表项,也即MBR只支持4个分区。
GPT是GUID磁碟分割表(GUID Partition Table)的缩写,含义“全局唯一标识磁盘分区表”,是一个实体硬盘的分区表的结构布局的标准。
GTP中也有一个MBR,其用来描述当前GPT的大小,这样GPT就不像传统的MBR只有512大小,这样GPT就可以支持更多的分区。
GPT的分区方案之所以比MBR更先进,是因为在GPT分区表头中可自定义分区数量的最大值,也就是说GPT分区表的大小不是固定的。在Windows中,微软设定GPT磁盘最大分区数量为128个。另外,GPT分区方案中逻辑块地址(LBA)采用64位二进制数表示,可以表示2^64个逻辑块地址。除此之外,GPT分区方案在硬盘的末端还有一个备份分区表,保证了分区信息不容易丢失。
MBR是和传统的Bios一起使用的,新电脑硬件默认使用新的UEFI系统,UEFI系统更强大,甚至可以有自己的UI和鼠标键盘,可以认为是一个小的操作系统。