Как проверить, указывают ли 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
   ...   
}

спасибо.

5 ответов


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

сравнение строк-это лучшее, что вы можете сделать. Обратите внимание, что с помощью String.Сравнить(str1 выглядит следующим образом, стр2, значение 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))
        ;
}    

работает и для файла...

(кстати, теоретически вопросы дублируются, но это оригинал, а другой-самый ответ...)

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