Как проверить, указывают ли 2 объекта DirectoryInfo на один и тот же каталог?

У меня есть 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
   ...   
}

Спасибо.

Ответ 1

В Linux вы можете сравнить номера INode двух файлов, так как они идентичны. Но под Windows нет такой концепции, по крайней мере, не то, что я знаю. Вам нужно будет использовать p/invoke для разрешения ссылок, если они есть.

Сравнение строк - лучшее, что вы можете сделать. Обратите внимание, что использование String.Compare(str1, str2, StringComparison.InvariantCultureIgnoreCase) немного быстрее, чем вы приближаетесь.

Ответ 2

Вместо этого вы можете использовать объекты 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

Ответ 3

Вдохновленный здесь:

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 теоретически вопросы повторяются, но это оригинал, а другой - самый ответный)...

НТН

Ответ 4

Нечувствительность к регистру - лучшее, что вы можете получить. Извлеките его в класс-помощник на всякий случай, если человечество придумает лучший метод.

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
}

Ответ 5

Некоторые методы расширения, которые я написал для недавнего проекта, включают в себя:

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