fat32
fat32文件系统结构:
FAT32文件系统由DBR及保留扇区,FAT1,FAT2和数据区组成:
- DBR及保留扇区:DBR的含义是DOS引导记录,也称为操作系统引导记录,在DBR之后往往会有一些保留扇区。
- FAT1:FAT的含义是文件分配表,FAT32一般有两份FAT,FAT1是第一份,也是主FAT。
- FAT2:FAT2是FAT32的第二份文件分配表,也是FAT1的备份。
- DATA:DATA也就是数据区,是FAT32文件系统的主要区域,其中包含目录区域。
首先根据MBR分区查找方法,找到FAT32分区起始位置。找到起始位置的第一个扇区(DBR)如下:
WinHex中查看其意义:
这个部分由跳转指令、OEM ID、BPB(BiOS参数)、拓展BPB、引导程序和结束标志组成。
- 跳转指令将呈现执行流程跳转到引导程序处;
- OEM ID由厂商指定,这里是msdos5.0;
- BPB记录文件系统相关的重要信息,由BPB和拓展BPB组成,具体参数解释如下:
FAT32分区的BPB字段表 | |||
字节位移 | 字段长度(字节) | 图8对应取值 | 名称和定义 |
0x0B | 2 | 0x0200 | 扇区字节数(Bytes Per sector) 硬件扇区的大小。本字段合法的十进制值有512、1024、2048和4096。对大多数磁盘来说,本字段的值为512 |
0x0D | 1 | 0x20 | 每簇扇区数(Sectors Per cluster),一簇中的扇区数。FAT32文件系统只能跟踪有限个簇(最多为4 294 967 296个),因此,通过增加每簇扇区数,可以使FAT32文件系统支持最大分区数。一个分区缺省的簇大小取决于该分区的大小。字段的合法十进制值有1、2、4、8、16、32、64和128。windows 2000的FAT32实现只能创建最大为32GB的分区。但是,Windows 2000能够访问由其他操作系统(Windows 95、OSR2及其以后的版本)所创建的更大的分区 |
0x0e | 2 | 0x0EA4 | 保留扇区数(Reserved Sector) 第一个FAT开始之前的扇区数,包括引导扇区。本字段的十进制值一般为32 |
0x10 | 1 | 0x02 | FAT数(Number of FAT) 该分区上FAT的副本数。本字段的值一般为2 |
0x11 | 2 | 0x0000 | 根目录项数(Root Entries)只有FAT12/FAT16使用此字段。FAT32分区本字段必须设置为 0 |
0x13 | 2 | 0x0000 | 小扇区数(Small Sector)(只有FAT12/FAT16使用此字段)FAT32分区本字段必须设置为0 |
0x15 | 1 | 0xF8 | 媒体描述符( Media Descriptor)提供有关媒体被使用的信息。值0xF8表示硬盘,0xF0表示高密度的3.5寸软盘。媒体描述符要用于MS-DOS FAT16磁盘,在Windows 2000中未被使用 |
0x16 | 2 | 0x0000 | 每FAT扇区数(Sectors Per FAT)只被FAT12/FAT16所使用,FAT32分区本字段必须设置为0 |
0x18 | 2 | 0x003F | 每道扇区数(Sectors Per Track) 包含使用INT13h的磁盘的“每道扇区数”几何结构值。该分区被多个磁头的柱面分成了多个磁道 |
0x1A | 2 | 0x00FF | 磁头数(Number of Head) 本字段包含使用INT 13h的磁盘的“磁头数”几何结构值。例如,在一张1.44MB 3.5英寸的软盘上,本字段的值为 2 |
0x1C | 4 | 0x04F4C000 | 隐藏扇区数(hidden Sector) 该分区上引导扇区之前的扇区数。在引导序列计算到根目录的数据区的绝对位移的过程中使用了该值。本字段一般只对那些在中断13h上可见的媒体有意义。在没有分区的媒体上它必须总是为0 |
0x20 | 4 | 0x028B3000 | 总扇区数(Large Sector) 本字段包含FAT32分区中总的扇区数 |
0x24 | 4 | 0x000028AE | 每FAT扇区数(Sectors Per FAT)(只被FAT32使用)该分区每个FAT所占的扇区数。计算机利用这个数和 FAT数以及隐藏扇区数(本表中所描述的)来决定根目录从哪里开始。该计算机还可以从目录中的项数决定该分区的用户数据区从哪里开始 |
0x28 | 2 | 0x0000 |
扩展标志(Extended Flag)(只被FAT32使用)该两个字节结构中各位的值为: 位0-3:活动 FAT数(从0开始计数,而不是1). 只有在不使用镜像时才有效 位4-6:保留 位7:0值意味着在运行时FAT被映射到所有的FAT 1值表示只有一个FAT是活动的 位8-15:保留 |
0x2A | 2 | 0x0000 | 文件系统版本(File ystem Version)只供FAT32使用,高字节是主要的修订号,而低字节是次要的修订号。本字段支持将来对该FAT32媒体类型进行扩展。如果本字段非零,以前的Windows版本将不支持这样的分区 |
0x2C | 4 | 0x00000002 | 根目录簇号(Root Cluster Number)(只供FAT32使用) 根目录第一簇的簇号。本字段的值一般为2,但不总是如此 |
0x30 | 2 | 0x0001 | 文件系统信息扇区号(File System Information SectorNumber)(只供FAT32使用) FAT32分区的保留区中的文件系统信息(File System Information, FSINFO)结构的扇区号。其值一般为1。在备份引导扇区(Backup Boot Sector)中保留了该FSINFO结构的一个副本,但是这个副本不保持更新 |
0x34 | 2 | 0x0006 | 备份引导扇区(只供FAT32使用) 为一个非零值,这个非零值表示该分区保存引导扇区的副本的保留区中的扇区号。本字段的值一般为6,建议不要使用其他值 |
0x36 | 12 | 12个字节均为0x00 | 保留(只供FAT32使用)供以后扩充使用的保留空间。本字段的值总为0 |
拓展BPB参数如下:
FAT32分区的扩展BPB字段 | |||
字节位移 | 字段长度(字节) | 图8对应取值 | 字段名称和定义 |
0x40 | 1 | 0x80 | 物理驱动器号( Physical Drive Number) 与BIOS物理驱动器号有关。软盘驱动器被标识为0x00,物理硬盘被标识为0x80,而与物理磁盘驱动器无关。一般地,在发出一个INT13h BIOS调用之前设置该值,具体指定所访问的设备。只有当该设备是一个引导设备时,这个值才有意义 |
0x41 | 1 | 0x00 | 保留(Reserved) FAT32分区总是将本字段的值设置为0 |
0x42 | 1 | 0x29 | 扩展引导标签(Extended Boot Signature) 本字段必须要有能被Windows 2000所识别的值0x28或0x29 |
0x43 | 4 | 0x33391CFE | 分区序号(Volume Serial Number) 在格式化磁盘时所产生的一个随机序号,它有助于区分磁盘 |
0x47 | 11 | “NO NAME” | 卷标(Volume Label) 本字段只能使用一次,它被用来保存卷标号。现在,卷标被作为一个特殊文件保存在根目录中 |
0x52 | 8 | “FAT32” | 系统ID(System ID) FAT32文件系统中一般取为”FAT32” |
对比上表分析:
02 00:每扇区512字节
20:每簇32个扇区,16Kb
0E A4:保留扇区3748个
02:2个FAT
00 00:根目录项数为0,FAT32必须为0
00 00:小扇区数为0,FAT32必须为0
F8:硬盘
00 00:每FAT扇区数为0,FAT32必须为0
00 3F:每磁道63扇区
00 FF:磁头数
04 F4 C0 00:隐藏扇区
02 8B 30 00:总扇区数
00 00 28 AE:每FAT扇区数
00 00:拓展标志
00 00:文件系统版本
00 00 00 02:根目录簇号
00 01:文件系统信息扇区号
00 06:备份扇区号
00 00 00 00 00 00 00 00 00 00 00 00:保留
80:物理硬盘
00:保留
29:拓展引导标签
E8 10 74 93:分区引导序号(随机)
4E 4F 20 4E 41 4D 45 20 20 20 20:卷标,”NO NAME”
46 41 54 33 32 20 20 20:系统ID,FAT32
FAT32文件系统在DBR的保留扇区中安排了一个文件系统信息扇区,用以记录数据区中空闲簇的数量及下一个空闲簇的簇号,该扇区一般在分区的1号扇区,也就是紧跟着DBR后的一个扇区,其内容如下:
52 52 61 41:拓展引导标签
接下来480字节未使用,如果安装了操作系统在这个分区上的话应该是有用的。
72 72 41 61:文件系统信息签名
00 14 56 7F:空闲簇数,约为20.3Gb
00 00 00 03:下一个空闲簇号
接下来的14个字节:未用
55 AA:结束标志
FAT32与FAT12、FAT16的区别是FAT32使用4个字节存储FAT簇号,而FAT12和FAT16使用较少的空间存储。
FAT表一般有两个,一个是备份。FAT表项编号从0开始,但是编号0表示FAT介质类型,编号1表示FAT文件系统错误标志,所以实际存储从2号开始。大文件占用多个簇的话,则FAT项纪录下一个FAT项编号,依次类推直到最后以“0F FF FF FF“表示文件末尾。文件至少占用一个簇,所以新建文件的时候,即使你只写入1字节的数据,它也会占用一个簇的空间。
接下来最重要的是如何定位FAT表所在的位置,然后是如何定位数据区所在位置。从DBR偏移0xB的两字节和00x0D的一字节可以看出,一簇为32扇区,每扇区512字节,一簇大小为16Kb。
按照最开始的图可以看到,FAT32文件系统最开始是DBR及保留扇区,接下来是 FAT表,接下来是数据区,有几个值与此有关:
DBR保留扇区数:位于DBR 0x0E偏移处,占两个字节,本文中是0E A4,即3748个扇区;
FAT数:位于DBR 0x10处,占一个字节,本文中该值是02,即有两个FAT表项;
每FAT扇区数:位于DBR 0x24处,占4个字节,本文是00 00 28 AE,即10414扇区。
因此可以知道:
FAT1起始位置为:DBR所在位置+保留扇区数*扇区大小,本文中绝对位置为:9E99D4800
FAT1如下图,此时该分区为空分区:
FAT表项的0和1号表项均不与实际的物理地址对应,从2号表项开始才与物理地址对应,2号表项为FAT2结束之后开始的簇,这个簇为根目录,根目录第一个文件目录项一般是卷标,所以即使刚格式化的分区,第2个FAT表项都是根目录,并且2号项是被占用的。
FAT2起始位置为FAT1+FAT扇区数*扇区大小:本文中的绝对位置为:9E9EEA400
FAT2如下图:
可以看到FAT1和FAT2是完全一样的。
数据区起始位置为:FAT2起始位置+FAT扇区数+扇区大小,本文绝对位置为:9EA400000
数据区起始位置(即根目录)如下图:
接下来先看一下FAT32短目录项的定义,短目录项就是文件名长8位、后缀为3位的文件,更长的文件名需要长文件名,后续再说。FAT32短文件目录项定义如下:
表14 FAT32短文件目录项32个字节的表示定义 | |||
字节偏移(16进制) | 字节数 | 定义 | |
0x0~0x7 | 8 | 文件名 | |
0x8~0xA | 3 | 扩展名 | |
0xB* | 1 | 属性字节 | 00000000(读写) |
00000001(只读) | |||
00000010(隐藏) | |||
00000100(系统) | |||
00001000(卷标) | |||
00010000(子目录) | |||
00100000(归档) | |||
0xC | 1 | 系统保留 | |
0xD | 1 | 创建时间的10毫秒位 | |
0xE~0xF | 2 | 文件创建时间 | |
0x10~0x11 | 2 | 文件创建日期 | |
0x12~0x13 | 2 | 文件最后访问日期 | |
0x14~0x15 | 2 | 文件起始簇号的高16位 | |
0x16~0x17 | 2 | 文件的最近修改时间 | |
0x18~0x19 | 2 | 文件的最近修改日期 | |
0x1A~0x1B | 2 | 文件起始簇号的低16位 | |
0x1C~0x1F | 4 | 表示文件的长度 |
因为FAT32使用4个字节表示文件或目录大小,因此当文件或目录大于4Gb时将会溢出,做截断处理。
FAT32文件系统分区根目录的文件和目录都存放在根目录区中,子目录文件和文件夹存放在子目录区中,以32字节为一项存放目录项(FDT),上图9EA400000处的第一个目录项0x0B处值为08,表示的是分区卷标,卷标名为”GGG”,由于分区还是空的,所以并没有其他目录项。
接下来新建一个空文件:
再看一下FAT表和根目录的变化:
看起来,只是新建文件的时候是不占用FAT表中的项的,所以并不占用空间,而只是在目录项中存着该文件的信息,往该文件写点东西:
可以看出来FAT中第3簇被占用并且只占用了一个簇,目录项中表示文件大小、文件起始簇低16位、文件最近修改时间的项有改变,00 00 00 0A表示的是文件大小,即10字节,00 03表示簇的低16位,高16位为00 00,和FAT中占用的簇一致,文件修改时间比较复杂,先看看时间日期的表示方法:
上边的最近修改时间为:4A AE,表示为:
01001(9) 010101(21) 01110(14*2),为:9:21:28,可以看到FAT32的文件修改时间为2秒,是很不精确的,创建时间有一个10毫秒位,相对精确
最近修改日期为:49 36,表示为:
0100100(36+1980=2016) 1001(9) 10110(22),为:2016.9.22,可以看到FAT32的时间还可以表示100年左右。
看看文件属性:
和分析的一致,占用空间为16Kb是因为一簇32扇区,一扇区512字节。
到第3簇看一下:
让文件变大一些:
再看看FAT和目录:
第3项存着第4项的名字,第4项存第5项的名字,以此类推直到0F FF FF FF表示文件结尾,这样就形成了一条链,要读取该文件的时候也只需要按照这条链去读取就可以完成读取了。
根目录在文件系统中占有重要作用,沿着它才能找到所需要的文件,看一下根目录怎么存储。在FAT32中将目录看做普通文件进行处理,目录项段文件名以32位为单位存储,长文件名后续再说,看一下如果根目录文件超过一个簇之后是不是以文件的链式存储。以下边的BAT文件建立很多个空文件,让根目录超过一个簇:
set /a num=1
:A
cd.>e:%num%.txt
set /a num+=1
goto A
只需要512个空文件就能让根目录超过一个簇了,所以在适当的时候结束批处理。
看看FAT:
根目录最终也形成了一个链,表示方法与普通文件看起来是一样的。看看根目录:
接下来我把这些文件删除掉。
可以看到FAT中文件所占用的簇都还在占用着,根目录中只是将表项第一字节置为E5,FDT第1字节又表明了该文件的状态,它有如下四种取值方式:
- a. 00H–目录项的空目录。
- b. E5H–表示该目录项曾经使用过,但文件已被删除。
- c. 2EH–表示子目录下的两个特殊文件 “. “或 “.. “目录项
- d. 其它任何字符–表示一个文件名(或目录名)的第一个字符的ASCII码值.
实际上删除之后只是把文件放到了回收站中,所以文件还在,清空回收站之后:
FAT中把FAT表项清空了,去看看之前文件占用的第3簇:
文件内容还在,所以删除文件只是将FAT表项清空。
其实删除文件之后只是在根目录中将文件项第一字节置为E5,然后建立$RECYCLEBIN的回收站目录,将删除的文件信息放在该目录下,如下图,然后从回收站还原的时候再放回原目录,但是这个具体是怎么弄的我也不清楚,大概流程是这样的。
删除时建立$RECYCLEBIN,在$RECYCLEBIN中设置有配置信息,在回收站还原时可以吧这些信息给还原回去,在回收站未清空时文件占用的簇依旧占用着,所以空间不会释放。
研究一下目录,删除分区后重新建了分区,然后建立了e:\aaa\bbb的空文件夹:
FAT:
根目录:
根目录有一个AAA子目录,看它所在簇为00 03,到第3簇看一下:
2E表示当前目录,2E 2E表示上级目录,BBB就是子目录,再到BBB所在的00 04簇看一下:
只有当前目录和上级目录。
事实上现在使用的基本都是长文件名,长文件名定义如下:
表15 FAT32长文件目录项32个字节的表示定义 | ||||
字节偏移 | 字节数 | 定义 | ||
0x0 | 1 | 属性字节位意义 | 7 | 保留未用 |
6 | 1表示长文件最后一个目录项 | |||
5 | 保留未用 | |||
4 | 顺序号数值 | |||
3 | ||||
2 | ||||
1 | ||||
0 | ||||
0x1~0xA | 10 | 长文件名unicode码① | ||
0xB | 1 | 长文件名目录项标志,取值0FH | ||
0xC | 1 | 系统保留 | ||
0xD | 1 | 校验值(根据短文件名计算得出) | ||
0xE~0x19 | 12 | 长文件名unicode码② | ||
0x1A~0x1B | 2 | 文件起始簇号(目前常置0) | ||
0x1C~0x1F | 4 | 长文件名unicode码③ |
新建一个”新建文本文档.txt”,看一下根目录:
长文件名使用Unicode存储,2字节为一个字,可以自己查一下新建文本文档对不对,我查是正确的。再建一个长长的文件名的文件,再看看根目录:
第一字节表示了文件名顺序和是否是文件名结束,其他放置unicode的部分放置unicode文件名,一直到unicode:00 00作为字符串结束标志,剩下的unicode部分填充为:FF FF,这样就能够支持很长很长的文件名了。
附:FAT记录项取值的意义:
FAT各系统记录项的取值含义 | |||
FAT12记录项的取值 | FAT16记录项的取值 | FAT32记录项的取值 | 对应簇的表现情况 |
000 | 0000 | 00000000 | 未分配的簇 |
002~FFF | 0002~FFEF | 00000002~FFFFFFEF | 已分配的簇 |
FF0~FF6 | FFF0~FFF6 | FFFFFFF0~FFFFFFF6 | 系统保留 |
FF7 | FFF7 | FFFFFFF7 | 坏簇 |
FF8~FFF | FFF8~FFFF | FFFFFFF8~FFFFFFFF | 文件结束簇 |
参考:
http://www.sjhf.net/pdf/fat.pdf
http://blog.chinaunix.net/uid-26913704-id-3213951.html
http://blog.csdn.net/mjx91282041/article/details/8904705
http://www.blogfshare.com/detail-fat32-filesys.html
相关阅读
Windows平台使用boost:1.到www.boost.org下载相应的代码包,请注意boost版本要和使用的VisualStudio版本想匹配, 比如我用的VS2013可
使用ServletFileUpload 实现文件上传 和获取文件信息
1、我使用的是ServletFileUpload来实现同个form表单中图片和文字信息的同时上传(支持多文件上传),首先我们先看下前端JSP页面的实例
windows下使用FFmpeg生成PCM音频文件并播放(通过命令的
一、PCM文件的定义 PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志。Windo
U盘是我们平常时拷贝文件和存储数据的好帮手,然后把本地的文件复制拷贝入U盘的过程中,有时候突然无法复制了,系统会提示磁盘被写保护