FAT32文件系统学习(2) —— FAT表
1、题外话
在继续本文学习FAT32文件系统之前,先来插入一点别的话题。我们都知道U盘有一个属性是容量,就拿笔者的U盘为例,笔者手上的U盘是金士顿的DataTraveler G3 4GB的一个U盘。电脑上显示的容量如图1所示为3.75GB。那么这个3.75GB是怎么计算出来的呢?

图 1 系统显示U盘属性
我们先来回顾一下上一篇BPB参数当中的Sectors(扇区总数)这个参数,这一参数代表了这个U盘在出厂时的总扇区数,笔者手上这个是7884672个,可以从图2中看到。其中每个扇区为512 B,也就是说总共可以容纳4036952064 B 约为 3.76GB 的数据。但是这其中一部分是要用来存放FAT32文件系统的相关信息参数的,比如FAT表,BPB等。我们这边来算一下,首先需要减去1016个保留扇区,还有两个FAT表总共是7684 * 2 = 15368个扇区,所示还剩下的字节数为4036952064 B - ( 1016 + 15368 ) * 512 B = 4028563456 B 正好是图中显示的容量。所以可以得出结论,系统显示的U盘容量 = ( 总扇区数 - 保留扇区数 - FAT表扇区数 * FAT表个数 ) * 512 B。经计算可得实际的使用率是99.79%。所以相对与整个U盘来说,FAT32文件系统用于存储相关信息部分的损耗是很小的。

图 2 笔者用上一篇中写的工具查看了U盘的各项参数
好了,接下来进入正题,继续学习FAT32文件系统的FAT表部分。
2、本文目录
3、FAT表的读取
首先FAT表一般来说有两张,另一张用于备份。两张表是前后紧挨在一起的,只要计算出了FAT1表的偏移之后加上FAT表的大小就可以得到FAT2表的偏移。FAT1表的偏移地址计算公式如下[4] :
FAT1表偏移 = 保留扇区数 * 每扇区字节数
由图2可知,在本例中,FAT1表的偏移 = 1016 * 512 B = 520192 = 0x7F000。同理:
FAT2表的偏移 = FAT1+FAT表的大小 = (保留扇区数 + FAT表扇区数) * 每扇区字节数
在本例中,FAT2表的偏移 = (1016 + 7684) * 512 B = 4454400 = 0x43F800。用上一篇中讲到的程序可以读取出两张FAT表的内容,一般情况下两张表的内容应该是完全一样的。笔者读取了第一张FAT表起始部分的内容,如图3所示:

图 3 FAT表起始部分内容
4、FAT表项
在分析FAT表之前先来说明一下FAT的构成。FAT表即文件分配表(File Allocation Table)。FAT32文件表是由一个个表项组成的一张表,其中每一个表项由一个32位的二进制组成,其值对应了相应簇的使用情况,如2号表项对应了2号簇的使用情况,3号表项对应了3号簇的使用情况,依此类推。(但是第0和第1项例外,下面会有说明)。每个表项对应数值的含义如表1所示[2]:
| 表项数值 | 对应含义 |
| 0x00000000 | 空闲簇,即表示可用 |
| 0x00000001 | 保留簇 |
| 0x00000002 - 0x0FFFFFEF | 被占用的簇,其值指向下一个簇号 |
| 0x0FFFFFF0 - 0x0FFFFFF6 | 保留值 |
| 0x0FFFFFF7 | 坏簇 |
| 0x0FFFFFF8 - 0x0FFFFFFF | 文件最后一个簇 |
表 1 表项数值含义
具体每一项填写的内容规则如下表所示:如果该簇是文件的最后一簇,填入的值为0x0FFFFFFF;如果该簇不是文件的最后一簇,则填入的值为该文件占用的下一簇号(所以我们可以看到在FAT32中文件是以簇链的形式保存起来的)。下面我们根据实际情况,图3来分析一下FAT表的含义。
FAT表第0项(0x00000000~0x00000003): 0x0FFFFF8
FAT表第1项(0x00000004~0x00000007): 0xFFFFFFFF
这两项不代表任何簇的使用情况,而是FAT表的表头,表征了介质描述,是固定值,所以0x00和0x01这两个簇号是不用的,簇号的下标从2开始。其中1号表项可能被用于记录脏标志,以说明文件系统没有被正常卸载或者磁盘表面存在错误。接下来
FAT表第2项(0x00000008~0x0000000B): 0x0FFFFFFF
第2项存储的是第2簇的使用情况,通常第2簇存储的是文件系统的根目录。虽然在FAT32文件系统中,根目录的位置不再硬性地固定,可以存储在分区内可寻址的任意簇内,不过通常根目录是最早建立的(格式化就生成了)目录表。所以,我们看到的情况基本上都是根目录首簇紧邻FAT2,占簇区顺序上的第1个簇(即2号簇)。同时,FAT32文件系统将根目录当做普通的数据文件来看,所有没有了目录项数的限制,在需要的时候可以分配空簇,存储更多的目录项[1]。
这一项的值为0x0FFFFFFF ,说明根目录占用且只占用了1个簇。
FAT表第3 ……
这里再穿插一点题外话,FAT32格式文件分配的最小单位是簇。也就是说你存储了一个实际大小1kB的文件,那么它占用的存储空间还是1簇(在这里换算成大小即为8*512B = 4KB)。笔者以一个实际的例子来说明一下:在U盘中放入一个8B大小的temp.txt文件,然后查看文件属性的时候发现其占用空间是4KB,和我们上面讲的理论符合。

图 4 temp.txt的大小和占用空间
看了下篇幅也差不多了,那么本文关于FAT表的部分到此结束。其实本来也没多少内容,笔者想到哪就扯到哪,胡扯了些其他的东西。剩下的数据区部分就留到下一篇当中再讲好了。同样的,本文当中有一些内容是笔者自己思考理解甚至推测出来的,如果有错误的地方欢迎指正,以免误人子弟了(笑)。
5、参考文献
1、FAT32文件系统的存储组织结构(一) http://blog.chinaunix.net/uid-26913704-id-3213948.html
2、FAT32 http://baike.baidu.com/view/45233.htm?fr=aladdin
3、基于U盘FAT32文件系统的分析 http://wenku.baidu.com/link?url=cIKgrwV66y4CoyuOEB1-OhjRY9tnXtIAoZuYEwDCjxbyRomSIiJgBAXGxq6LudfwuopUpYhiVd8TjxrBFoVyPs0NX3OqbnoWjyn4ZAx60Wi
4、FAT 32 文件格式 http://blog.csdn.net/shrekmu/article/details/5950414
FAT32文件系统学习(2) —— FAT表的更多相关文章
- FAT32文件系统学习(3) —— 数据区(DATA区)
FAT32文件系统学习(3) —— 数据区(DATA区) 今天继续学习FAT32文件系统的数据区部分(Data区).其实这一篇应该是最有意思的,我们可以通过在U盘内放入一些文件,然后在程序中读取出来: ...
- FAT32文件系统学习(上)
2011-06-02 22:30:48 目的:需要编写SD读图片的底层驱动程序.所以要了解一个SD卡常用文件系统基本概念.累计学习用时2.5小时. 一,FAT32的保留区 1,引导扇区 :引导扇区是F ...
- FAT32文件系统学习(1) —— BPB的理解
FAT 32 文件系统学习 1.本文的目标 本文将通过实际读取一个FAT32格式的U盘来简单了解和学习FAT32文件系统的格式.虽然目前windwos操作系统的主流文件系统格式是NTFS,但是FAT3 ...
- FAT和FAT32文件系统的原理
[转自] http://www.sjhf.net/Article/sjhfdoc/200404/1.html 一.硬盘的物理结构: 硬盘存储数据是根据电.磁转换原理实现的.硬盘由一个或几个表面 ...
- 基于stm32f103zet6的FAT16文件系统学习1(初识FAT16)
有了之前读写block的基础之后,准备弄个文件系统,之前没有接触过这东西,所以有很多都晕晕的,但是看到fat的源代码之后还是挺有信心的,因为之前一直过uboot,所以这个文件当然是小巫见大巫了.首先来 ...
- FAT文件系统学习和思考
FAT(File Allocation Table)文件系统 前两天面试,导师说我基础差,要赶紧补起来了.今天晚上看了FAT32文件系统,基本的信息都是百度百科中"FAT文件系统" ...
- 【转载】FAT32文件系统详解
硬盘是用来存储数据的,为了使用和管理方便,这些数据以文件的形式存储在硬盘上.任何操作系统都有自己的文件管理系统,不同的文件系统又有各自不同的逻辑组织方式.例如:常见的文件系统有FAT,NTFS,EXT ...
- FAT32文件系统
- U盘FAT32文件系统
一.FAT文件系统分为四个部分 参考别人的博客 1.http://blog.163.com/ourhappines@126/blog/static/121363154201311811495492/ ...
随机推荐
- Java标识符
相关内容: JAVA标识符: 定义 组成规则 常见的命名规则 包 类和接口 方法.变量 常量 首发时间:2017-06-22 20:40 修改时间: 2018-03-16 14:01 :修改了标题,修 ...
- 谨慎使用MyBatis自动生成Where语句
最近监控到类似这样一个慢查询: select XX_time from XXOrderInfo WHERE ( OrderId is not null and OrderId = N'xxxx') x ...
- scaffold-dbcontext 命令使用说明
工具的scaffold-dbcontext(数据库上下文脚手架)指令来生成models和context. 指令详细介绍: Scaffold-DbContext [-Connection] <St ...
- 开发中解决Access-Control-Allow-Origin跨域问题的Chrome神器插件,安装及使用
背景: 笔者在用cordova开发安卓程序的时候在安卓设备上不存在跨域问题,但是在浏览器端模拟调试的时候却出现了Access-Control-Allow-Origin跨域问题,报错如下 No 'Acc ...
- MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系
2016-12-23 17:29 宋利兵 作者:宋利兵 来源:MySQL代码研究(mysqlcode) 0.导读 本文重点介绍了InnoDB的crash safe和binlog之间的关系,以及2阶段提 ...
- Android分区
1. Android 分区: 2. Android各个分区的作用: 2.1 modem分区 实现手机必需的通信功能,大家通常所的刷RADIO就是刷写modem分区,在所有适配的ROM中这部分是不动,否 ...
- python基础学习11----函数
一.函数的定义 def 函数名(参数列表): 函数体 return语句 return语句不写或后边不加任何对象即为return None 二.函数的参数 无参数 def func1(): print( ...
- windows注册表
如何导入与导出注册表 进入注册表编辑器,选择“文件”“导出”命令,打开“导出注册表文件”对话框.选择保存位置并为其取名,单击保存即可完成注册表的备份. 打开注册表编辑器,选择“文件”“导入”命令,打开 ...
- Linux系统优化之设置swappiness值提高MySQL查询性能
对MySQL来说,操作系统层面的优化也可以值得考虑一下:就是swappiness. swappiness的大小主要对如何使用swap分区有着密切的联系. 来看一下: [root@chaofeng ~] ...
- Rafy框架
l 什么是Rafy框架? -------- Rafy 是一个面向企业级开发的插件化快速开发框架. l Rafy的优点是什么? ------快速开发.产品线工程.一套代码可同时生成并运行 C/S.单 ...