FAT-32上的Unicode文件名?

时间:2013-10-21 20:05:44

标签: windows winapi unicode codepages fat32

据我所知 - NTFS支持Unicode文件名(作为Micorsoft声称的UTF-16?)。

但官方MSDN文档对于在FAT-32上用于存储文件名(文件路径)的代码页非常模糊。

这里说 OEM代码页(我假设为CP437)用于存储文件名:http://msdn.microsoft.com/en-us/library/windows/desktop/dd317748.aspx

但事实证明,可能有不同的 OEM代码页,其中CP437就是其中之一:http://msdn.microsoft.com/en-us/library/windows/desktop/dd317752.aspx

我们现在所有像 mount 这样的实用程序都支持更多不同的FAT代码页,而不仅仅是OEM代码页设置。

那么FAT-32文件名的实际cdepage是什么?这取决于FAT卷创建时的系统代码页? FAT可以支持真正的双字节字符集代码页,如UTF-16吗?或者像UTF-8这样的多字节字符集代码页是限制吗?

更具体的问题: 当我使用CreateFileW函数(如MSDN所述,使用UTF-16作为文件名代码页)在FAT-32卷上创建文件时会发生什么?

2 个答案:

答案 0 :(得分:8)

您可能需要在此进行试验。这是一个很好的问题,我不是100%自信,但是:

  

那么FAT-32文件名的实际代码页是什么?这取决于FAT卷创建时的系统代码页?

“OEM代码页”,无论系统是什么。

  

FAT可以支持真正的双字节字符集代码页,如UTF-16吗?或者像UTF-8这样的多字节字符集代码页是限制吗?

不,我不相信FAT可以直接使用UTF-16或UTF-8。也就是说,Microsoft以带外方式存储Unicode文件名。因此文件有两个文件名。 (这也是你可以拥有超过8.3个字符文件名的方式。)

  

更具体的问题:当我使用CreateFileW函数(如MSDN所述,使用UTF-16作为文件名代码页)在FAT-32卷上创建文件时会发生什么?

传递给CreateFileW的Unicode文件名直接存储在带外文件名中。它被重新编码到OEM代码页(无论在系统上发生什么)并放在那里。如果无法将其转换为OEM代码页或超过8.3个字符,Windows将调用该文件,如FILENA~1.TXT

对这些答案的一些引用:

首先,this page告诉我们OEM代码页!= Windows代码页:

  

创建FAT文件的非Unicode应用程序有时必须使用标准C运行时库转换函数在Windows代码页字符集和OEM代码页字符集之间进行转换。使用文件系统函数的Unicode实现,不必执行此类转换。

在典型的美国系统中,OEM代码页为"CP437",但Windows代码页为Windows-1252(我认为,FooA调用使用Windows代码页,通常美国机器上的Windows-1252,但取决于区域设置)。

如果您有FAT卷可用,您可以看到这一点。 Windows-1252中不存在字符“Σ”(U + 03a3),但它位于CP437中。您可以使用dir /X查看短文件名和长文件名。使用名为asdfΣ.txt的文件,您会看到:

ASDFΣ.TXT    asdfΣ.txt

但是,使用名为“asdfΛ.txt”的文件(Λ在CP437或Windows-1252中不存在),您将看到:

ASDF~1.TXT   asdf?.txt

(您可能会看到?,因为cmd.exe的字体无法显示Λ。)

有关长文件名的信息,请参阅this Wikipedia article

另外,有趣的是,如果您将文件命名为“asdf©.txt”,您可能会得到:

ASDFC.TXT    asdfc.txt

......我不是百分百肯定在这里,但我认为Windows巧妙地决定用“c”代替©,同样也用于显示它。如果您将字体更改为基于栅格的字体(如Consolas),您将看到:

ASDFC.TXT    asdf©.txt

这就是你应该使用FooW函数的原因。

答案 1 :(得分:2)

基本FAT或FAT32目录条目仅支持当前OEM代码页中的短名称(旧的DOS 8.3格式)。但是,在Windows下使用的VFAT(支持长文件名的FAT)可以为每个文件存储一个额外的,所谓的long filename,格式为UTF-16。