正在验证与.Net的路径相等性

本文关键字:路径 Net 验证 | 更新日期: 2023-09-27 18:07:52

比较.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/

正在验证与.Net的路径相等性

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可以同时使用文件和目录。

不确定你的第二个例子。

尽管这是我发现的一个旧帖子。

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

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

根据评论中给出的建议,忽略案例比较

Path.GetFullPath(path1).Equals(Path.GetFullPath(path2),StringComparison.CurrentCultureIgnoreCase)

我喜欢@bob ashcraft的答案,但我认为它应该扩展一点。这是我的(没有足够的代表评论他的:((

/// <summary>
/// Tests if paths are physically/logically the same.
/// Physical: C:'DATA == c:''dAtA'')
/// Logical: C:'DATA == ''SERVER'DATA)
/// Must have pathA write and pathB read permission to test for logical equality.
/// </summary>
public static bool TryIsSamePath(string pathA, string pathB, out string errorMsg)
{
    var ret = false;
    errorMsg = string.Empty;
    try
    {
    // If either are blank it's not valid.
    if (string.IsNullOrWhiteSpace(pathA)) { throw new ArgumentNullException(nameof(pathA)); }
    else if (string.IsNullOrWhiteSpace(pathB)) { throw new ArgumentNullException(nameof(pathB)); }
    // Test if they are the exact same physical path.
    ret = System.IO.Path.GetFullPath(pathA).Equals(System.IO.Path.GetFullPath(pathB));
    // If not physically the same, test for logical.
    // Create a temp file on pathA; if it exists on pathB too then they're the same.
    if (!ret)
    {
        var tempPathA = System.IO.Path.Combine(pathA, System.DateTime.Now.Ticks.ToString() + ".~");
        var tempPathB = System.IO.Path.Combine(pathB, System.IO.Path.GetFileName(tempPathA));
        using (var tempPathAFileStream = System.IO.File.Create(tempPathA)) { }
        ret = System.IO.File.Exists(tempPathB);
        System.IO.File.Delete(tempPathA);
    }
    }
    catch (Exception exc)
    {
    // Return the error message but don't rethrow.
    errorMsg = exc.Message;
    }
    return ret;
}

根据其他人的报告,Path.GetFullPathFileInfo.FullName提供本地文件的规范化版本。将UNC路径标准化以进行比较需要更多的工作,但值得庆幸的是,Brian Pedersen在他的博客上发布了一个方便的MRU(Method Ready to Use(来做你需要做的事情,标题恰如其分,叫做从UNC路径获取本地路径。一旦将其添加到代码中,就会有一个静态GetPath方法,该方法将UNC路径作为其唯一参数,并将其规范化为本地路径。我试了一下,结果如广告宣传的那样。

使用扩展方法的语法很好

你可以有一个很好的语法如下:

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提供的好的路径示例。

我也遇到了这个问题,但我尝试了一种不同的方法,使用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
}

我用来确定两个路径字符串是否指向同一位置的一个非常简单的方法是在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.

此代码通过首先检查路径末尾的'/并忽略这些末尾(如果存在(来比较相等性。

Linux版本:

public static bool PathEquals(this string left, string right) =>
    left.TrimEnd('/', '''') == right.TrimEnd('/', '''');

Windows版本(不区分大小写(:

public static bool PathEquals(this string left, string right) =>
    string.Equals(left.TrimEnd('/', ''''), right.TrimEnd('/', ''''), StringComparison.OrdinalIgnoreCase);

您可以使用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
}

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

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