2009-11-25 5 views
11

Tengo 2 DirectoryInfo objetos y quiero comprobar si apuntan al mismo directorio. Además de comparar su nombre completo, ¿hay otras formas mejores de hacerlo? Por favor, ignore el caso de los enlaces.¿Cómo comprobar si 2 objetos de DirectoryInfo apuntan al mismo directorio?

Esto es lo que tengo.

DirectoryInfo di1 = new DirectoryInfo(@"c:\temp"); 
DirectoryInfo di2 = new DirectoryInfo(@"C:\TEMP"); 

if (di1.FullName.ToUpperInvariant() == di2.FullName.ToUpperInvariant()) 
{ // they are the same 
    ... 
} 

Gracias.

+0

pregunta relacionada: http://stackoverflow.com/q/2281531/1082063 –

Respuesta

6

En Linux puede comparar los números de INode de los dos archivos si son idénticos. Pero en Windows no existe ese concepto, al menos no que yo sepa. Debería usar p/invoke para resolver los enlaces, si los hubiera.

La comparación de cadenas es lo mejor que puede hacer. Tenga en cuenta que usar String.Compare (str1, str2, StringComparison.InvariantCultureIgnoreCase) es un poco más rápido de lo que se aproxima.

+0

era Hay algo mal con mi respuesta? – codymanix

+0

¿Qué pasa con esta respuesta? ¿Por qué estaba marcado abajo? Encuentro bueno el consejo de usar String.Compare(). – tranmq

+1

Esto es básicamente lo mismo que la solución provista en la pregunta. El mejor enfoque es usar Uri, que manejará diferentes formatos, etc. –

0

La comparación insensible a las mayúsculas y minúsculas es lo mejor que puede obtener. Se extrae a una clase de ayuda en caso de que la humanidad encuentre un mejor método.

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

y uso:

if (di1.IsEqualTo(di2)) 
{ 
    // Code here 
} 
6

puede utilizar objetos de Uri en su lugar. Sin embargo, sus objetos Uri deben apuntar a un "archivo" dentro de estos directorios. Ese archivo en realidad no tiene que existir.

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

    } 

Esto imprimirá:

u1 == u2 ? True 
u2 == u3 ? True 
+0

Esta debería ser la respuesta, ya que cubre el borde casos como "\ ..\ "y es más robusto, aunque necesita una pequeña solución –

+1

pero hay un problema, traduce cosas como% 51 en letras en lugar de dejarlas, por lo que si prueba esta ruta: ' @ "c: \ test \ rootQpath " @" C: \ TEST \ .. \ TEST \ ROOT% 51PATH "' Devolverá verdadero –

+0

Mientras 'C: \' funcionará, esto arrojará una 'UriFormatException' si la ruta está en forma de' C : '(omitiendo el' \ ') como' Path.Combine' resultará en algo como esto 'C: log.txt' – Petaflop

2

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

Obras para el archivo también ...

(BTW teóricamente preguntas son duplicado, pero esto es el original y el otro es el más respondido ...)

HTH

0

Algunos métodos de extensión que escribí para un proyecto reciente incluye uno que lo hará:

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