【问题标题】:Verifying path equality with .Net使用 .Net 验证路径是否相等
【发布时间】:2011-11-12 18:49:56
【问题描述】:

在 .Net 中比较两个路径以确定它们是否指向同一个文件或目录的最佳方法是什么?

  1. 如何验证这些是否相同:

    c:\Some Dir\SOME FILE.XXX
    C:\\\SOME DIR\some file.xxx
    
  2. 更好的是:有没有办法验证这些路径指向某个网络驱动器上的同一个文件:

    h:\Some File.xxx
    \\Some Host\Some Share\Some File.xxx
    

更新:

Kent Boogaart 正确回答了我的第一个问题;但我仍然很想知道我的第二个问题是否有解决方案,即比较网络驱动器上文件和目录的路径。

更新 2(我的两个问题的综合答案):

问题 1:本地和/或网络文件和目录

c:\Some Dir\SOME FILE.XXX
C:\\\SOME DIR\some file.xxx

答案:使用System.IO.Path.GetFullPath,例如:

var path1 = Path.GetFullPath(@"c:\Some Dir\SOME FILE.XXX");
var path2 = Path.GetFullPath(@"C:\\\SOME DIR\subdir\..\some file.xxx");

// outputs true
Console.WriteLine("{0} == {1} ? {2}", path1, path2, string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase));

问题 2:本地和/或网络文件和目录

答案:使用 GetPath 方法,如发布在 http://briancaos.wordpress.com/2009/03/05/get-local-path-from-unc-path/

【问题讨论】:

标签: c# .net path


【解决方案1】:
var path1 = Path.GetFullPath(@"c:\Some Dir\SOME FILE.XXX");
var path2 = Path.GetFullPath(@"C:\\\SOME DIR\subdir\..\some file.xxx");

// outputs true
Console.WriteLine("{0} == {1} ? {2}", path1, path2, string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase));

在 Windows 上忽略大小写只是一个好主意。您可以以类似的方式使用FileInfo.FullName,但Path 将适用于文件和目录。

不确定你的第二个例子。

【讨论】:

  • 为什么new FileInfo(@"c:\").Equals(new FileInfo(@"c:\")) 评估为false?这真的应该是这样做的方式..
  • 比较目录时,应考虑尾部斜杠。例如,@"A:\dir" 不等于 @"A:\dir\"GetFullPath
  • Path.GetFullPath(@"C:\src") 返回 @"C:\src"Path.GetFullPath(@"C:\src\") 返回 @"C:\src\"。换句话说,即使这些路径是等价的,上述方法在这种极端情况下也会失败。
  • 为什么这个答案使用 OrdinalIgnoreCase 而不是 CurrentCultureIgnoreCase?这些文件名字符串来自用户。在我看来,这意味着您需要使用当前文化进行正确比较。 Ordinal 仅对机器生成的字符串有效,例如在已知模式中解析 XML 标记。我是不是误会了什么?
  • @srm 因为文件路径是文化上独立的数据。见docs.microsoft.com/en-us/dotnet/standard/base-types/…
【解决方案2】:

确保两个路径引用同一个文件的唯一一种方法是打开和比较文件。至少您可以实例化 FileInfo 对象并比较以下属性: CreationTime, FullName, Size 等。在某种程度上,它可以保证两个路径引用同一个文件。

【讨论】:

  • 好吧,对于本地文件(至少是同一文件系统上的文件),我希望您不需要这样做。对于我的第二种情况,也许你是对的,但这就是我问这个问题的原因......
【解决方案3】:

为什么不为每个文件创建一个哈希值并比较它们呢?如果它们相同,则可以合理地确定它们是同一个文件。

【讨论】:

  • 或两个独立但相同的文件。
【解决方案4】:

您可以使用 FileInfo!

string Path_test_1="c:\\main.h";
string Path_test_2="c:\\\\main.h";

var path1=new FileInfo(Path_test_1)
var path2=new FileInfo(Path_test_2)
if(path1.FullName==path2.FullName){

//two path equals
}

【讨论】:

  • 区分大小写。用“Main”和“main”试试你的代码
【解决方案5】:

正如其他人所报告的,Path.GetFullPathFileInfo.FullName 提供本地文件的规范化版本。标准化 UNC 路径以进行比较涉及更多,但值得庆幸的是,Brian Pedersen 在他的博客上发布了一个方便的 MRU(即用方法)来完全满足您的需求,标题为 Get local path from UNC path。将其添加到代码中后,您将拥有一个静态 GetPath 方法,该方法将 UNC 路径作为其唯一参数并将其规范化为本地路径。我试了一下,效果和宣传的一样。

【讨论】:

    【解决方案6】:

    虽然这是我找到的旧帖子。

    使用 Path.GetFullpath 我可以解决我的问题 例如。

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

    【讨论】:

    • 这在返回false的情况下不起作用:Path.GetFullPath(@"C:\tfs\").Equals(Path.GetFullPath(@"C:\TFS"))
    【解决方案7】:

    使用扩展方法的好语法

    你可以有这样一个很好的语法:

    string path1 = @"c:\Some Dir\SOME FILE.XXX";
    string path2 = @"C:\\\SOME DIR\subdir\..\some file.xxx";
    
    bool equals = path1.PathEquals(path2); // true
    

    通过扩展方法的实现:

    public static class StringExtensions {
        public static bool PathEquals(this string path1, string path2) {
            return Path.GetFullPath(path1)
                .Equals(Path.GetFullPath(path2), StringComparison.InvariantCultureIgnoreCase);
        }
    }
    

    感谢 Kent Boogaart 提供了很好的示例路径。

    【讨论】:

      【解决方案8】:

      我也遇到过这个问题,但我尝试了另一种方法,使用 Uri 类。到目前为止,我发现它非常有前途:)

      var sourceUri = new Uri(sourcePath);
      var targetUri = new Uri(targetPath);
      
      if (string.Compare(sourceUri.AbsoluteUri, targetUri.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase) != 0 
      || string.Compare(sourceUri.Host, targetUri.Host, StringComparison.InvariantCultureIgnoreCase) != 0)
                  {
      // this block evaluates if the source path and target path are NOT equal
      }
      

      【讨论】:

        【解决方案9】:

        我用来确定两个路径字符串是否指向同一个位置的一个非常简单的方法是在 Path1 中创建一个临时文件并查看它是否显示在 Path2 中。它仅限于您具有写入权限的位置,但如果您可以忍受,那就很容易了!这是我的 VB.NET 代码(可以轻松转换为 C#)……

        Public Function SamePath(Path1 As String, Path2 As String) As String
        
        '  Returns: "T" if Path1 and Path2 are the same,
        '           "F" if they are not, or
        '               Error Message Text
        
        Try
           Path1 = Path.Combine(Path1, Now.Ticks.ToString & ".~")
           Path2 = Path.Combine(Path2, Path.GetFileName(Path1))
        
           File.Create(Path1).Close
        
           If File.Exists(Path2) Then
              Path2 = "T"
           Else
              Path2 = "F"
           End If
        
           File.Delete(Path1)
        
        Catch ex As Exception
           Path2 = ex.Message
        
        End Try
        
        Return Path2
        
        End Function
        

        我将结果作为字符串返回,以便在用户输入一些垃圾时提供错误消息。我还使用 Now.Ticks 作为“保证”的唯一文件名,但还有其他方式,例如 Guid.NewGuid。

        【讨论】:

          猜你喜欢
          • 2021-02-13
          • 2020-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-31
          • 2018-10-03
          • 2020-07-04
          相关资源
          最近更新 更多