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?
How would one verify that these are the same:
c:\Some Dir\SOME FILE.XXX C:\\\SOME DIR\some file.xxx
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.
精彩评论