Win32 文件名比较
有谁知道 Win32 在处理不区分大小写的文件名时使用什么文化设置?
这是根据用户的文化而变化的东西,还是 Win32 使用文化不变的大小写规则?
Does anyone know what culture settings Win32 uses when dealing with case-insensitive files names?
Is this something that varies based on the user's culture, or are the casing rules that Win32 uses culture invariant?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
大概的答案是
以正确的方式比较 Unicode 文件名。
基本上,建议将两个字符串都大写(使用
CharUpper
,CharUpperBuff
,或LCMapString
),然后使用二进制比较进行比较(即 memcmp 或 wmemcmp,而不是具有不变语言环境的 CompareString) 。 文件系统不进行 Unicode 规范化,并且大小写规则不依赖于区域设置。不幸的是,在处理大小写规则在不同版本的 Unicode 中发生变化的字符时,会出现不明确的情况,但这已经是您能做到的最好的了。
An approximate answer is at
Comparing Unicode file names the right way.
Basically, the recommendation is to uppercase both strings (using
CharUpper
,CharUpperBuff
, orLCMapString
), then compare using a binary comparison (i.e. memcmp or wmemcmp, not CompareString with an invariant locale). The file system doesn't do Unicode normalization, and the case rules are not dependent on locale settings.There are unfortunate ambiguous cases when dealing with characters whose casing rules have changed across different versions of Unicode, but it's about as good as you can do.
比较本机代码中的文件名 和 不比较文件名 是关于这个主题的几篇很好的博客文章。 第一个包含 OrdinalIgnoreCaseCompareStrings 的 C/C++ 代码,第二个告诉您这对于文件名并不总是有效,以及如何缓解这种情况。
Comparing file names in native code and Don't compare filenames are a couple of good blog posts on this topic. The first has C/C++ code for OrdinalIgnoreCaseCompareStrings, and the second tells you how that doesn't always work for filenames and what to do to mitigate that.
如果您使用 .NET,Microsoft 的官方建议是使用
StringComparison.OrdinalIgnoreCase
用于比较和ToUpperInvariant
用于标准化(稍后使用Ordinal
比较)。 这也适用于注册表项和值、环境变量等。请参阅使用字符串的新建议有关更多详细信息,请参阅 Microsoft .NET 2.0。
请注意,虽然它在 NTFS 上可靠,但在网络共享等情况下可能会失败。 请参阅@SteveSteiner 的答案和他帖子中的链接以获取解决方案。
If you're using .NET, the official recommendation from Microsoft is to use
StringComparison.OrdinalIgnoreCase
for comparison andToUpperInvariant
for normalization (to be later compared usingOrdinal
comparison). This also applies to Registry keys and values, environment variables etc.See New Recommendations for Using Strings in Microsoft .NET 2.0 for more details.
Note that while it's reliable on NTFS, it can fail with network shares, for example. See @SteveSteiner's answer and links in his post for solutions.
根据 Windows 驱动程序示例 FastFAT 和 CDFS,它使用 < code>RtlUpcaseUnicodeString 将字符串转换为大写。 根据 Ghidra 的简要介绍,它使用一个名为
NLS_UPCASE
的内部函数,其行为基于您当前的系统代码页。According to Windows Driver Samples FastFAT and CDFS, it uses
RtlUpcaseUnicodeString
to convert a string to uppercase. According to a brief look in Ghidra, that uses an internal function namedNLS_UPCASE
, whose behavior is based on your current system codepage.