开发者

Verifying path equality with .Net

What is the best way to compare two paths in .Net to figure out if they point to the same file or directory?

  1. How would one verify that these are the same:

    c:\Some Dir\SOME FILE.XXX
    C:\\\SOME DIR\some file.xxx
    
  2. Even better: is there a way to verify that these paths point to the same file on some network drive:

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

UPDATE:

Kent Boogaart has answered my first question correctly; but I`m still curious to see if there is a solution to my second question about comparing paths of files and directories on a network drive.

UPDATE 2 (combined answers for my two questions):

Question 1: local and/or network files and directories

c开发者_高级运维:\Some Dir\SOME FILE.XXX
C:\\\SOME DIR\some file.xxx

Answer: use System.IO.Path.GetFullPath as exemplified with:

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));

Question 2: local and/or network files and directories

Answer: Use the GetPath method as posted on http://briancaos.wordpress.com/2009/03/05/get-local-path-from-unc-path/


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));

Ignoring case is only a good idea on Windows. You can use FileInfo.FullName in a similar fashion, but Path will work with both files and directories.

Not sure about your second example.


Although it's an old thread posting as i found one.

Using Path.GetFullpath I could solve my Issue eg.

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


As reported by others, Path.GetFullPath or FileInfo.FullName provide normalized versions of local files. Normalizing a UNC path for comparison is quite a bit more involved but, thankfully, Brian Pedersen has posted a handy MRU (Method Ready to Use) to do exactly what you need on his blog, aptly titled Get local path from UNC path. Once you add this to your code, you then have a static GetPath method that takes a UNC path as its sole argument and normalizes it to a local path. I gave it a quick try and it works as advertised.


Nice syntax with the use of extension methods

You can have a nice syntax like this:

string path1 = @"c:\Some Dir\SOME FILE.XXX";
string path2 = @"C:\\\SOME DIR\subdir\..\some file.xxx";

bool equals = path1.PathEquals(path2); // true

With the implementation of an extension method:

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

Thanks to Kent Boogaart for the nice example paths.


I had this problem too, but I tried a different approach, using the Uri class. I found it to be very promising so far :)

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
}


A very simple approach I use to determine if two path strings point to the same location is to create a temp file in Path1 and see if it shows up in Path2. It is limited to locations you have write-access to, but if you can live with that, it’s easy! Here’s my VB.NET code (which can easily be converted to 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

I return the result as a string so I can provide an error message if the user enters some garbage. I’m also using Now.Ticks as a “guaranteed” unique file name but there are other ways, like Guid.NewGuid.


This code compares equality by first checking for \ or / at the end of a path and ignoring those endings if they exist there.

Linux version:

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

Windows version (case insensitive):

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


you can use 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
}


Only one way to ensure that two paths references the same file is to open and compare files. At least you can instantiate FileInfo object and compare properties like: CreationTime, FullName, Size, etc. In some approximation it gives you a guarantee that two paths references the same file.


Why not create a hash of each file and compare them? If they are the same, you can be reasonably sure they are the same file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜