有谁知道 Win32 在处理不区分大小写的文件名时使用什么文化设置?
这是根据用户的文化而变化的东西,还是 Win32 使用文化不变的大小写规则?
有谁知道 Win32 在处理不区分大小写的文件名时使用什么文化设置?
这是根据用户的文化而变化的东西,还是 Win32 使用文化不变的大小写规则?
一个近似的答案是 正确比较 Unicode 文件名。
基本上,建议将两个字符串都大写(使用CharUpper
、、CharUpperBuff
或LCMapString
),然后使用二进制比较(即 memcmp 或 wmemcmp,而不是具有不变语言环境的 CompareString)进行比较。文件系统不进行 Unicode 规范化,大小写规则不依赖于区域设置。
不幸的是,在处理大小写规则在不同版本的 Unicode 中发生变化的字符时会出现模棱两可的情况,但它几乎可以做到。
比较本机代码中的文件名和不比较文件名是关于这个主题的几篇很好的博客文章。第一个有用于 OrdinalIgnoreCaseCompareStrings 的 C/C++ 代码,第二个告诉您这并不总是适用于文件名以及如何缓解这种情况。
然后是Unicode问题。虽然这些新的
OrdinalIgnoreCase
字符串比较算法非常适合您的本地 NTFS 驱动器,但它们可能无法在您的 FAT 驱动器或网络共享上产生正确的答案。那么答案是什么?如果可能,让文件系统告诉您。
CreateFile
可以告诉你给定的文件名是否存在。只需选择正确的创作倾向。如果需要与句柄进行比较,可以经常使用GetFileInformationByHandle
; 看dwVolumeSerialNumber
/nFileIndexHigh
/nFileIndexLow
。
如果您使用的是.NET,Microsoft 的官方建议是StringComparison.OrdinalIgnoreCase
用于比较和ToUpperInvariant
规范化(稍后使用比较进行Ordinal
比较)。这也适用于注册表项和值、环境变量等。
有关更多详细信息,请参阅Microsoft .NET 2.0 中使用字符串的新建议。
请注意,虽然它在 NTFS 上是可靠的,但它可能会因网络共享而失败,例如。请参阅@SteveSteiner 的答案和他的帖子中的链接以获取解决方案。
根据Windows Driver Samples FastFAT 和 CDFS,它用于RtlUpcaseUnicodeString
将字符串转换为大写。根据 Ghidra 的简要介绍,它使用名为 的内部函数NLS_UPCASE
,其行为基于您当前的系统代码页。