FAT32的长文件名处理

FAT32的长文件名处理

名词解释:Long File Names (LFNs) 

1. Directory Entry

文件系统的文件名信息主要是在目录项中进行记录的,一个目录项(Directory Entry)单元由32字节组成,各字节的示意如图1。这是一个标准的目录项的全部内容。


图1

可见此处一个目录项中可以存放的文件名只有8个字节,那么当大于8个字节长度的文件名该如何存储?

2. Additional Entries

以一个简单粗暴的方式开始吧: 格式化U盘->在根目录下新建文件"abcdefghijklmnopqrstuvwxyz.txt",此时我们查看FAT的目录项内容可以发现:

FAT32的长文件名处理_第1张图片

图2

  • 首先,长文件名的文件名信息也是在FAT目录项中存储,但是一个32字节的标准的目录项无法存储大于8字节长度的文件名,此时FAT则会为该长文件名附加多个单元项,与标准的目录项中各字节的表示有差别,但是长度依然还是32字节。
  • 其次,与短文件名一样,长文件名依然会占用一个Directory Entry来存储图1中的文件信息,不同的是,在8个字节的FileName项,Byte[0,5]6个字节中填充长文件名的前6字节,Byte[6]填充字符“~”,Byte[7]从“1”开始,按当前文件夹中文件名重名需要选取从“1”递增的数字,可见是为了防止文件重名。
  • 另外,文件名在目录项的记录中,offset=0x0C 的字节是用于指示文件名和扩展名的大小写,当长文件名时,该字节被置为“0x00”,此时可见与大写文件名和大写扩展名的表示没有什么区别了,那么FAT是怎么区分这样两个文件的?

长文件名在目录中除了用一个标准目录项记录信息外,还增加了若干个信息项,就叫做"Additional Entries"吧,参考自维基百科。

3.长文件名的重命名

再通过以下实验,看windows是怎么处理FAT的,然后就可以一步步验证并找出长文件名在FAT中怎么存在的。

鉴于长文件名在FileName项中的存储机制,我们新建文件名时:用大写字母创建,则可有大小写区分;以‘~1’结尾,则可看到长短文件名的冲突;只创建空文件,因为只需要查看目录项,不需要文件内容:

目前我们需要创建的是“ABCDEF~1.TXT”,为了和"abcdefghijklmnopqrstuvwxyz.txt",在目录项中重名。看FAT是如何处理的:

FAT32的长文件名处理_第2张图片

图3

只是添加了一个短文件名,目录项的变化却比正常情况下大多了。以上我分成了3个部分:

  • 第一部分都是0xE5开头的,那么它们是已被删除项;
  • 第二部分可以对比图2,可以看到差别:目录项中的文件名被重新命名为"ABCDEF~2.TXT";
  • 第三部分才是刚才新建的“ABCDEF~1.TXT”的文件目录项信息;

为什么不是被命名为“xxxx~2”而是以前的文件名被改?怎么理解FAT的以上行为呢?

  • 首先从文件创建时间可以肯定以上分析没有错;
  • 其次,短文件名的目录项中FileName项完全反应真实文件名(暂时排除大小写问题);
  • 最后,图2中的红色框即长文件名的目录项,与图3最下方比较,只有创建时间不同。如果是你,总也不会通过时间戳去区别这两个文件吧,那么FAT当然也不会。所以它将原来的长文件名在目录项中重命名,就出现了第一部分中的被删除项以及第二部分中的新建项。那么还多出来了第一部分中的最后两项,从文件类型来看是个临时产物,但具体是怎么产出来的,它不重要。

其实我一直有一个问题,为什么FAT要将临时文件,或重命名后无用的以前的旧文件名的目录项一直保留着?不是很浪费空间吗,这些中间产物完全可以不用留。我不熟悉windows OS,所以暂时不深究,但这不妨碍我的做法,我只在FAT的目录项中写最终结果,没有中间临时文件,且目前为止没有问题。

那么问题又来了:

仅看图3,"ABCDEF~1.TXT"和"ABCDEF~2.TXT"只是差别只有一个字节的文件名而已,为什么其中一个就是长文件名。

其实,图3和图2的信息量很大,继续看图说话,图3 Part2中的Additional Entries:

4.长短文件名的区分

"ABCDEF~2.TXT"的目录项信息之上,还有三组附加信息项,很有规律:

  • 每个附加项的文件类型为0x0F;
  • 最低层的附加项第一个字节从0x01开始;
  • 每往上多一层附加项,该项第一字节基于下一层的数字递增;
  • 直到最上一层,第一字节在递增的基础上再加0x40;

目录项中没有关于附加项总数的信息,貌似只能硬着头皮往上一层找是否第一字节为0x01,再往上找一项,第一字节是否递增,或者是否结束来判断并获取当前文件完整的文件名。

那么会不会恰好发生下面这么一件事儿?

4.1. 新建一个文件,文件名为"C. t x t.TXT"或者"C.txt"且把文件类型设置为0x0F,达到目录项中显示以下内容的效果?


答,不能,首先' '空格的ASCII码不是0x00而是0x20, 其次该文件后缀为.TXT, 那么它的文件类型不会为0x000000, 最后, 也是最重要的, 文件名中包含字符'.'则已被认作长文件名处理;显然"C.txt"更无力产生以上效果

4.2. 新建一个文件,,达到目录项中显示以下内容的效果?


答,用英文,即单字节字符,没有可以显示的ASCII为0x01的字符。用双字节字符,先不不论"bcde"四个字符,找出对应0x0161的字符"š.TXT"新建文件你就会发现这也行不通。因为所有双字节字符在FAT中都被当做长文件名处理。


所以,不会再有那么多“那么”了。图2就是一个完整的不会有任何冲突和异议的长文件名在FAT中的表示。

至于要怎么把你的长文件名写入FAT表目录项以及从FAT表目录项中识别出长文件名,我就不乱戳戳点点了。




你可能感兴趣的:(FAT,FAT,文件系统)