【问题标题】:.NET How to compare two Strings that represent filenames ignoring case correctly.NET如何比较两个代表文件名的字符串忽略大小写正确
【发布时间】:2009-11-18 15:19:47
【问题描述】:

鉴于(至少在 NTFS 上)Windows 上的文件系统不区分大小写,我想将 String fileAString fileB 进行比较:

fileA.Equals(fileB, StringComparison.CurrentCultureIgnoreCase)

然后问题就变成了我应该使用哪种文化,默认的当前(ui?)文化就足够了吗?我似乎找不到任何用于此目的的 BCL 方法。

【问题讨论】:

  • 出于这些目的,我总是建议 CultureInfo.InvariantCulture

标签: c# filesystems culture case-insensitive


【解决方案1】:

你应该使用StringComparison.OrdinalIgnoreCase,根据Best Practices for Using Strings in the .NET Framework

文件系统、注册表项和值以及环境变量的字符串行为最好用 StringComparison.OrdinalIgnoreCase 表示。

如果您使用文化来匹配字符串,您可能会遇到例如名称“häl.gif”和“hal.gif”会被视为匹配的情况。

【讨论】:

  • 它确实回答了这个问题。不应使用培养物。 NTFS 文件名比较是有序的。
  • 我试图在 MSDN 上找到支持这一点的官方声明,但找不到。如果有人找到,请链接到它。
【解决方案2】:

这是不可能做到可靠的。

是的,文件系统的大小写转换不区分大小写。

但是大小写转换表存储在文件系统本身(对于NTFS),它确实会在版本之间发生变化(例如Vista大小写转换表被带到了Unicode 5级别,所以Vista NTFS和XP NTFS有不同大小写转换规则)。

重要的是格式化文件系统的操作系统,而不是当前的操作系统。

然后您可能会遇到其他文件系统的各种问题(Mac OS 会进行某种 Unicode 规范化(不是标准的)),Linux 不会做任何事情,但 Samba(实现 Windows 文件共享协议)会.并且有 Windows 以外的其他表。

如果我将一个字母映射到 Linux 或 Mac OS 共享的网络磁盘会发生什么?

一般来说,您永远不应该尝试比较文件名。如果您想知道它是否存在,请尝试访问它。

【讨论】:

    【解决方案3】:

    马库斯,

    您可能想查看另一个 StackOverflow 问题的答案,该问题非常相似:Win32 File Name Comparison,其中又提到了http://www.siao2.com/2005/10/17/481600.aspx

    按照同一问题的另一个答案中的链接并进一步挖掘,我发现了以下 MSDN 文章 http://msdn.microsoft.com/en-us/library/ms973919.aspx 。一般来说,它值得一读,但在文件名比较方面,它建议使用 StringComparison.OrdinalIgnoreCase。请参阅文章中的表 1,其中包含文件路径作为处理的数据类型之一或以下引用:

    因此,在解释文件名、cookie 或任何其他可能出现类似 å 组合的内容时,序号比较仍然提供最透明和最合适的行为。

    希望这会有所帮助, 波阿斯

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 那是用现在的文化,所以和他已有的文化是一样的。
      • 是的,抱歉,我稍后才发现。
      【解决方案5】:

      您可以使用 InvariantCulture(查看 http://msdn.microsoft.com/en-us/library/4c5zdc6a.aspx)。

      在你的例子中:

      
      FileA.Equals(FileB,StringComparison.InvariantCultureIgnoreCase )
      

      【讨论】:

      • 不要 - 这与 NTFS 规则不一致。使用序数比较。
      【解决方案6】:

      我试过了。

      Path.GetFullPath(path1).Equals(Path.GetFullPath(path2))
      

      【讨论】:

      • 更好Path.GetFullPath(path1).TrimEnd(Path.DirectorySeparatorChar).Equals(Path.GetFullPath(path2).TrimEnd(Path.DirectorySeparatorChar))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2023-04-10
      • 2010-10-26
      • 1970-01-01
      相关资源
      最近更新 更多