imjacob的专栏

首页博文目录订阅
正 文

子目录FDT的簇链结构

(2009/1/16 22:04)
引子:
我原来只知道fat文件目录表中存放的是各个文件的信息属性,而没有想过各个父子目录和父子文件是连续存放,存放在一起的吗?今天看fat的程序时想到了这个问题,于是从网上找了篇文章。
上面问题的答案是父子关系的目录和文件都不是存放在一起的。同一个层次下的目录和文件才是放在一起的。
根目录FDT找到子目录DFT的方式竟然和文件目录表找文件分配表的方式一模一样。于是在子目录FDT跨扇区的情况下,同一个层次下的扇区也形成了簇链。
这时候新问题来了,那怎么区分到底是数据还是子目录呢?我想数据区本身是不知道的,FAT当然也不会知道,但是文件目录表知道阿,那不就好了。反正一切的一切还不是从文件目录表开始搜索到的吗?
下面是我看得那篇文章。


 
  子目录FDT的簇链结构收藏

在FAT文件系统中的目录结构是层次性的树形结构,根目录下可以包含文件和子目录,子目录下可以包含文件并且还可以再包含子目录。如图6-7所示就是一个树形目录结构的例子。
                          

                                图6-7 FAT文件系统中的数形目录结构
在FDT中,子目录的管理与普通文件相同,一个子目录文件在FDT表中也占据32个字节的目录项。但是,子目录项中的文件长度总为零,尽管它的文件长度实际上不为零,它的意义在于不能使用不同的DOS读写命令来读写一个子目录文件。
1.子目录FDT中的目录项
当前目录为子目录时,在使用DOS命令DIR列文件目录清单时,通常可以看到前两项特殊文件:
“·”表示当前目录
“··”表示上一级目录
这两项同其它子目录一样也没有长度。“·”项所报告的“首簇号”是子目录FDT第一个扇区所在的簇;“··”所报告的“首簇号”是上一级目录的开始簇号。如果上一级目录是根目录,则该簇号值被置成0。系统利用此结构来实现目录之间的双向联系。
只有当文件需要时,系统才给文件分配数据区空间。存放数据的空间是按每次一个簇的方式来分配的。分配的时候,系统跳过已分配的簇,第一个遇到的空簇就是下一个将要分配的簇,此时系统并不考虑簇在磁盘上的物理位置。同时,文件已被删除后空出来的簇也可以分配给新的文件,这样做可使磁盘空间得到有效的利用。
可以说,数据区空间的使用是在文件分配表和文件目录表的统一控制下完成,每个文件所有的簇在文件分配表中都是链接在一起的。
需要注意的是:若使用DOS命令“MD”在磁盘上建立子目录SUB1,我们在FDT中可查到SUB1目录项的第0字节的值不是2E,而是“S”的ASCII码值53(如表6-7所示),
并且子目录SUB1中的所有文件不占根目录的FDT,而是按SUB1的首簇号2AH在相应的逻辑扇区中建立子SUB1自己的文件目录表FDT。这是因为 DOS是将子目录作为一个普通文件的文件目录项来处理的。只是在第11字节的文件属性位设为10H,以表示为子目录项。在文件目录项中的第0字节为 2EH,也仅是出现在子目录FDT中的第一、第二两个目录项中(如表6-8所示)。
假设一个FAT16结构逻辑硬盘根目录的文件目录表FDT的起始扇区为129(81H),共32(20H)个扇区。用DEBUG中的命令“L 100 2 81 20”读出硬盘逻辑81H扇区开始的20H个扇区,来查看硬盘根目录的FDT,可得到一个如表6-7所示的根目录文件目录表(FDT)。
表6-7 根目录文件目录表(FDT)

xxxx:0000

xxxx:0010

49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00

00 00 00 00 00 00 C0 32-BF 1C 07 00 46 9F 00 00

IO      SYS'...

  .....2....F..

xxxx:0020

xxxx:0030

4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00

00 00 00 00 00 00 C0 32-BF 1C 4F 00 FA 94 00 00

MSDOS   SYS'...

  ......2..O...

xxxx:0040

xxxx:0050

43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00

00 00 00 00 00 00 C0 32-BF 1C 5B 00 75 D5 00 00

COMMAND COM....

  ......2..[.u.

xxxx:0060

xxxx:0070

53 55 42 31 20 20 20 20-20 20 20 10 00 00 00 00

00 00 00 00 00 00 DD 8C-8B 28 03 00 00 00 00 00

SUB1       ....

  .......(.....


从显示结果可以看出,SUB1表项的第11字节的值为10H,表明SUB1不是一个文件,而是一个子目录,其首簇号为第3簇。
在根目录下的文件或子目录在磁盘上的存储位置(逻辑扇区号)按以下公式计算:
逻辑扇区号=1+2*FAT的扇区数+根FDT+(首簇号-2)*每簇扇区数
所以,子目录SUB1的FDT存放的首扇区号应该是:
首扇区号=1+2*201扇区+32扇区+(3-2)*8扇区
=443扇区(1BBH扇区)
用DEBUG命令"-L 00 2 1BB 1"将第1BBH扇区的SUB1子目录FDT的1个扇区内容读入00开始的内容,然后用"-D 00"命令显示子目录SUB1的FDT部分内容。
2.子目录下FDT表的扩充
根目录FDT表和子目录中的FDT表有两个最大的区别:
·根FDT表的扇区数是固定不变的,所以根目录下能够存放的文件或子目录数量是有限的,而子目录FDT表的扇区数是固定的,因而其存放的文件或目录数量也 没有限制。
·根FDT表的所有扇区在物理上是连续存放的,而子目录FDT表的所有扇区在物理是不连续存放的,这些FDT的扇区之间存在一种逻辑上的链接关系。
我们知道,文件系统是将子目录作为一个普通文件的文件目录项来管理的。FDT中的一个扇区最多只能存放16个文件项,对于子目录FDT的首扇区来说,子目录下的两个特殊目录“·”和“··”要占该扇区的前64字节,也就是说该扇区只能存放14个文件的文件目录项。显然,子目录不止有14个文件,那么14个文件以后的那些子目录中,文件的文件目录项又是存放在什么地方呢?操作系统又是如何查找它们的呢?
与普通文件在FAT中的簇号一样,子目录FDT的第一个扇区的簇号及其扩展扇区的簇号在FAT中也会形成一个簇号链,并且也是以FF8H---FFFH(或FFF8H---FFFFH)作为最后一个FDT扇区的结束标志。
例如,假设一个子目录的FDT共有3个扇区组成,在根FDT中查得该子目录的首簇号为a,再从FAT表中查得该子目录FDT扇区的簇链关系为“a=>b=>c”。假如该子目录下有一个文件Text.txt,系统查找该文件的步骤如下:
步骤1:在根FDT中查得子目录的目录项,从该目录项中得到该子目录的首簇号为a,该簇所在的扇区即为子目录FDT的首扇区。并在该扇区中查找文件Text.txt。
步骤2:如果没有找到,则在FAT表中从簇号a开始查得该子目录FDT的下一个扇区的簇号为b,然后再在该扇区中查找文件Text.txt。
步骤3:如果在簇号b扇区中仍然没有找到,则在FAT表中从簇号b查得该子目录FDT的下一个扇区的簇号为c,然后再在该扇区中查找文件Text.txt。
步骤4:如此继续,直到查到该文件的目录表项。
如果直到该子目录FDT簇链的最后一个扇区仍然没有找到该文件,就报告查找失败。
原载:http://blog.csdn.net/qianjintianguo/archive/2006/05/08/712593.aspx


后记,我想了下,这片文章说根FDT是32个扇区,或者根FDT是固定大小扇区数吗,我觉得是有问题的。就我所知,在FAT12和FAT16中,根FDT在系统中,所以有根目录数目有限的说法,但是在FAT32中,根FDT放在了数据区,根目录只要在存储空间足够的情况下是可以无限的,那这样还给FDT一个固定大小可能吗?你怎么给呢?我不知道标准是怎么实现的。
===========================================================
今天继续上次那个未完的问题,有查了点资料,思考了一下。
FAT32对根目录FDT的管理和子目录FDT和普通文件可能是一样的,也都能形成簇链。
 根目录区(ROOT区)不再是固定区域、固定大小,可看作是数据区的一部分。因为根目录已改为根目录文件,采用与子目录文件相同的管理方式,一般情况下从第二簇开始使用,大小视需要增加,因此根目录下的文件数目不再受最多512的限制。FAT16文件系统的根目录区(ROOT区)是固定区域、固定大小的,是从FAT区之后紧接着的32个扇区,最多保存512个目录项,作为系统区的一部分。
FAT32将根目录也视作一个目录文件,使用一个簇链(Cluster   Chain),RootDirStartClus正是这个链的起始簇号。FAT32有个专门放BIGFATBOOTFSINFO结构的扇区,该结构包含了剩余簇个数,下一个空闲簇号等信息。这个扇区通常紧接着引导扇区。
FAT32的BPB定义如下:
typedef   struct
{
        word   BytesPerSector;   //每扇区字节数
        byte   SectorsPerCluster;   //每簇扇区数
        word   ReservedSectors;   //保留扇区数
        byte   NumberOfFATs;   //FAT的个数
        word   RootEntries;   //根目录项数(FAT32不用)
        word   TotalSectors;   //分区总扇区数(FAT32不用)
        byte   MediaDescriptor;   //分区介质标识
        word   SectorsPerFAT;   //每个FAT占的扇区数(FAT32不用)
        word   SectorsPerTrack;   //每道扇区数
        word   Heads;   //磁头数
        dword   HiddenSectors;   //隐含扇区数
        dword   BigTotalSectors;   //分区总扇区数
        dword   BigSectorsPerFat;   //每个FAT占的扇区数
        word   ExtFlags;   //扩展标志
        word   FS_Version;   //文件系统版本
        dword   RootDirStartClus;   //根目录起始簇号
        word   FSInfoSec;   //指向包含BIGFATBOOTFSINFO结构的扇区
        word   BkUpBootSec;   //后备引导区的位置
        byte   Reserved[12];   //备用
}BPB_FAT32;
http://topic.csdn.net/u/20070404/14/9cf16a56-bfbc-4c8d-83ea-455ce8e8ab18.html

 FAT32的根目录肯定是可以不连续的,   只是第一个簇的位置是固定的(02簇,   这和原来的一致,其实这个不一定,由RootDirStartClus决定,但一般是2//by imjacob),   如果你的根目录下的文件的目录项数从未超过128(是项数,不是文件和目录数,因为可能有长文件名),   那么自然不需要访问FAT区,   否则,   必须访问FAT区才能访问完整的根目录区.
http://topic.csdn.net/t/20020825/22/969274.html#

 FAT32的根目录大小是不固定的,而且它在FAT表中的首簇也不一定非是第二簇,你可以根据BPB表找到根目录的首簇,然后从首簇开始根据FAT表可以找出所有根目录所占用的簇,把簇的总和跟每簇扇区数相乘就得到根目录所占用的总扇区数。  
  FAT32对于根目录的管理与一般文件基本相似,只不过将它的首簇地址记录在BPB表中以定位。
另外,关于FAT,这篇文章《硬盘 FAT 文件系统原理的详细分析》http://www.tl800.com/js_fat.html写得非常好,缺点就是太长了。
评 论
还没有网友评论,欢迎您第一个评论!
博 主
进入imjacob的首页
博客名称:雅克的一府
日志总数:514
评论数量:901
访问次数:1870020
建立时间:2006/11/23 20:52
导 航
公 告
Locations of visitors to this page 本博客主要用于个人学习与资料收藏。当然大家应该读了之后也能学到不少东西。其中大多数资料都是来自网络,我转载时尽可能地表明文章出处与原作者姓名,但由于很多资料经多人转载,已不清楚原作者信息与出处,所以未表明相关…
评 论
链 接

ARM+LINUX 嵌入式博客
http://blog.chinaunix.net/u1/58780/index.html

嵌入式软件
http://blog.csdn.net/embeddedsoft

诚诚恳恳做人踏踏实实编程
http://blog.sina.com.cn/u/1244756857 

和我风格相似的一个blog
http://blogger.org.cn/blog/m…