FATFS配置长文件名,为何跟编码转换有关

        要打开FATFS的长文件名功能,必须添加OEMCP与Unicode的编码转换函数,同时也就要把OEMCP与Unicode的编码转换数组添加进来,这是为什么呢?

        OEMCP在936代码页下就是GBK,这个编码转换也就是GBK和Unicode互转。FATFS是使用的GBK编码,文件的短文件名也是GBK编码,因此不需要转换,可是文件的长文件名使用的UTF-16编码,这是Unicode的一种编码方式(关于Unicode和UTF-16的关系,去这儿)。因此要读取长文件名必须得先把UTF-16编码的长文件名转换为GBK才可以。

以下如详细内容:

        FAT32文件系统在为文件分配短文件名(SFN)目录项的同时会为其分配长文件名(LFN)目录项。SFN目录项中包含了文件名的前8个字符、时间、大小、起始簇号等文件信息,而LFN名目录项中只包含文件的名字。如果一个文件的文件名超过了8个字符,则会为其名字截短后为其建立短文件名。将短文件名存储在短文件名目录项中。长文件名则存放在长文件名目录项中。长文件名(LFN)目录项有以下特点:

1、LFN和SFN目录项结构在相同位置有一个属性标志字节,LFN目录项使用一个特定的属性值,以说明它是一个长文件名项。
2、项中除标志位外的其他字节,使用UTF-16编码,存储13个Unicode字符的文件名,每个字符占用两个字节。
3、如果文件名长于13个字符,则继续为其分配LFN项,直到够用为止。
4、所有LFN都包含一个校验和,通过这个校验和将其与相应的SFN项关联起来。
5、一个文件的所有LFN项按倒序排列在它的SFN项前面,即文件名的第一部分距离SFN是最近的。

一、长文件名目录项数据结构:

《FATFS配置长文件名,为何跟编码转换有关》

详细解释如下:
【1】0x00~0x00:1个字节,长文件名目录项的序列号,一个文件的第一个长文件名序列号为1,然后依次递增。如果是该文件的最后一个长文件名目录项,则将该目录项的序号与0x40进行“或(OR)运算”的结果写入该位置。如果该长文件名目录项对应的文件或子目录被删除,则将该字节设置成删除标志0xE5。
【2】0x01~0x0A:5个字节,长文件名的第1~5个字符。长文件名使用Unicode码,每个字符需要两个字节的空间。如果文件名结束但还有未使用的字节,则会在文件名后先填充两个字节的“00”,然后开始使用0xFF填充。
【3】0x0B~0x0B:1个字节,长目录项的属性标志,一定是0x0F。
【4】0x0C~0x0C:保留。
【5】0x0D~0x0D:1个字节,校验和。如果一个文件的长文件名需要几个长文件名目录项进行存储,则这些长文件名目录项具有相同的校验和。
【6】0x0E~0x19:12个字节,文件名的第6~11个字符,未使用的字节用0xFF填充。
【7】0x1A~0x1B:2个字节,保留。

【8】0x1C~0x1F:4个字节,文件名的第12~13个字符,未使用的字节用0xFF填充。
二、长文件名目录项实例分析
首先我们在根目录下建立一个名字为“amp3foryatoumadebyfgd20090808summer.txt”的文件,然后用winhex来看看它的长文件名目录项,如下图:

《FATFS配置长文件名,为何跟编码转换有关》

《FATFS配置长文件名,为何跟编码转换有关》

        上面看的第二幅图就是由“amp3foryatoumadebyfgd20090808summer.txt”文件的短文件名目录项和长文件名目录项组成。最下面的一个目录项就是该文件的短文件名目录项,我们可以看到,“amp3foryatoumadebyfgd20090808summer.txt”文件名被截断,取出前六个字符“AMP3FO”(注意短文件名是不分大小写的),然后加上“~1”,最后加上它的扩展名。由短文件名向上,是它的长文件名目录项。“amp3foryatoumadebyfgd20090808summer.txt”共有39个字符,每个长文件名目录项可以记录13个字符,因此需要3个长文件名目录项。短文件名目录项向上第一个小方框卷定的目录项是它的第一个长文件名目录项,向上依次为2、3号,从每个长文件名目录项的第一个字节可以看出他们的序号。
【1】我们先来看第一个内容:
     0x0B字节处的“0F”表示这是一个长文件名目录项。
    0x00字节处的“01”表示这是该文件的第一个长文件名目录项。
    0x01~0x0A字节处的10个字节为文件名的第1~5个字符“amp3f”。0x0E~0x19子接触的12个字节是文件名的第6~11个字符“oryato”,0x1C~0x1F处的4个字节是文件名的第12~13个字符“um”。
【2】第二个长文件名目录项的第一个字节“02”表示这是该文件的第二个长文件名目录项,各部分字节含义由读者自行分析。
【3】第三个长文件名目录项的第一个字节为“43”,是0x40和0x03进行或运算的结果。说明这是该文件的第3个长文件名目录项,也是最后一个。
【4】 我们分别看3个长文件名目录项0x0D字节处的值——0x8B,这是长文件名目录项的校验和。说明这3个目录项同属一个长文件名目录项。

点赞