据我所知 - 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卷上创建文件时会发生什么?
答案 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。