How to check whether 2 DirectoryInfo objects are pointing to the same directory?

前端 未结 5 2004
眼角桃花
眼角桃花 2020-12-10 14:11

I have 2 DirectoryInfo objects and want to check if they are pointing to the same directory. Besides comparing their Fullname, are there any other better ways

相关标签:
5条回答
  • 2020-12-10 14:14

    Case-insensitive comparison is the best you can get. Extract it to a helper class just in case mankind comes up with a better method.

    public static class DirectoryInfoExtensions
    {
        public static bool IsEqualTo(this DirectoryInfo left, DirectoryInfo right)
        {
            return left.FullName.ToUpperInvariant() == right.FullName.ToUpperInvariant();
        }
    }
    

    and use:

    if (di1.IsEqualTo(di2))
    {
        // Code here
    }
    
    0 讨论(0)
  • 2020-12-10 14:21

    Some extension methods that I wrote for a recent project includes one that will do it:

        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));
        }
    
    0 讨论(0)
  • 2020-12-10 14:33

    Inspired from here:

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

    Works for file too...

    (BTW theoretically questions are duplicate, but this is the original and the other one is the most answered one...)

    HTH

    0 讨论(0)
  • 2020-12-10 14:38

    Under Linux you could compare the INode numbers of the two files wheather they are identical. But under Windows there is no such concept, at least not that I know off. You would need to use p/invoke to resolve the links if any.

    Comparing strings is the best you can do. Note that using String.Compare(str1, str2, StringComparison.InvariantCultureIgnoreCase) is a bit faster than you approach.

    0 讨论(0)
  • 2020-12-10 14:40

    You can use Uri objects instead. However, your Uri objects must point to a "file" inside these directories. That file doesn't actually have to exist.

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

    This will print out:

    u1 == u2 ? True
    u2 == u3 ? True
    
    0 讨论(0)
提交回复
热议问题