我有2个 DirectoryInfo
对象,并想检查它们是否指向同一目录。除了比较他们的全名,还有其他更好的方法吗?请忽略链接的情况。
这就是我所拥有的。
DirectoryInfo di1 = new DirectoryInfo(@"c:\temp");
DirectoryInfo di2 = new DirectoryInfo(@"C:\TEMP");
if (di1.FullName.ToUpperInvariant() == di2.FullName.ToUpperInvariant())
{ // they are the same
...
}
谢谢。
在Linux下,您可以比较它们相同的两个文件的INode编号。但在Windows下,没有这样的概念,至少我不知道。您需要使用p / invoke来解析链接(如果有的话)。
比较字符串是您可以做的最好的。请注意,使用String.Compare(str1,str2,StringComparison.InvariantCultureIgnoreCase)比您的方法快一点。
您可以改用Uri对象。但是,您的Uri对象必须指向这些目录中的“文件”。该文件实际上不必存在。
private void CompareStrings()
{
string path1 = @"c:\test\rootpath";
string path2 = @"C:\TEST\..\TEST\ROOTPATH";
string path3 = @"C:\TeSt\RoOtPaTh\";
string file1 = Path.Combine(path1, "log.txt");
string file2 = Path.Combine(path2, "log.txt");
string file3 = Path.Combine(path3, "log.txt");
Uri u1 = new Uri(file1);
Uri u2 = new Uri(file2);
Uri u3 = new Uri(file3);
Trace.WriteLine(string.Format("u1 == u2 ? {0}", u1 == u2));
Trace.WriteLine(string.Format("u2 == u3 ? {0}", u2 == u3));
}
这将打印出来:
u1 == u2 ? True
u2 == u3 ? True
灵感来自 这里:
static public bool SameDirectory(string path1, string path2)
{
return (
0 == String.Compare(
System.IO.Path.GetFullPath(path1).TrimEnd('\\'),
System.IO.Path.GetFullPath(path2).TrimEnd('\\'),
StringComparison.InvariantCultureIgnoreCase))
;
}
也适用于文件......
(BTW理论上问题是重复的,但这是原始的,另一个是答案最多的......)
HTH
不区分大小写的比较是您可以获得的最佳结果。将它解压缩到一个帮助类,以防万一人类提出了更好的方法。
public static class DirectoryInfoExtensions
{
public static bool IsEqualTo(this DirectoryInfo left, DirectoryInfo right)
{
return left.FullName.ToUpperInvariant() == right.FullName.ToUpperInvariant();
}
}
并使用:
if (di1.IsEqualTo(di2))
{
// Code here
}
我为最近的项目编写的一些扩展方法包括一个可以执行此操作的扩展方法:
public static bool IsSame(this DirectoryInfo that, DirectoryInfo other)
{
// zip extension wouldn't work here because it truncates the longer
// enumerable, resulting in false positive
var e1 = that.EnumeratePathDirectories().GetEnumerator();
var e2 = other.EnumeratePathDirectories().GetEnumerator();
while (true)
{
var m1 = e1.MoveNext();
var m2 = e2.MoveNext();
if (m1 != m2) return false; // not same length
if (!m1) return true; // finished enumerating with no differences found
if (!e1.Current.Name.Trim().Equals(e2.Current.Name.Trim(), StringComparison.InvariantCultureIgnoreCase))
return false; // current folder in paths differ
}
}
public static IEnumerable<DirectoryInfo> EnumeratePathDirectories(this DirectoryInfo di)
{
var stack = new Stack<DirectoryInfo>();
DirectoryInfo current = di;
while (current != null)
{
stack.Push(current);
current = current.Parent;
}
return stack;
}
// irrelevant for this question, but still useful:
public static bool IsSame(this FileInfo that, FileInfo other)
{
return that.Name.Trim().Equals(other.Name.Trim(), StringComparison.InvariantCultureIgnoreCase) &&
that.Directory.IsSame(other.Directory);
}
public static IEnumerable<DirectoryInfo> EnumeratePathDirectories(this FileInfo fi)
{
return fi.Directory.EnumeratePathDirectories();
}
public static bool StartsWith(this FileInfo fi, DirectoryInfo directory)
{
return fi.Directory.StartsWith(directory);
}
public static bool StartsWith(this DirectoryInfo di, DirectoryInfo directory)
{
return di.EnumeratePathDirectories().Any(d => d.IsSame(directory));
}