2009-03-08 12 views
8

¿Cuál es el equivalente a PathCanonicalize en C#?PathCanonicalize equivalent en C#

Uso: Necesito adivinar si dos rutas de archivos se refieren al mismo archivo (sin acceso al disco). Mi enfoque típico ha sido arrojarlo a través de algunos filtros como MakeAbsolute y PathCanonicalize, y luego hacer una comparación insensible a mayúsculas y minúsculas.

Respuesta

12

rápida y sucia:

En el pasado he creado un objeto FileInfo de la cadena de ruta y luego se usa la propiedad FullName. Esto elimina todos los ... \ 's y los. \.

Por supuesto podría INTEROP:

[DllImport("shlwapi", EntryPoint="PathCanonicalize")] 
    private static extern bool PathCanonicalize(
     StringBuilder lpszDst, 
     string lpszSrc 
    ); 
5

3 soluciones:

mejor de los casos, en la que son 100% seguro de que el proceso de llamada tendrá acceso completo al sistema de archivos. advertencia: permiso en un cuadro de la producción puede ser complicado

public static string PathCombineAndCanonicalize1(string path1, string path2) 
    { 
     string combined = Path.Combine(path1, path2); 
     combined = Path.GetFullPath(combined); 
     return combined; 
    } 

embargo, no siempre somos libres. A menudo necesitas hacer la aritmética de cuerdas sin permiso. Hay un llamado nativo para esto. advertencia: recurre a la llamada nativa

public static string PathCombineAndCanonicalize2(string path1, string path2) 
    { 
     string combined = Path.Combine(path1, path2); 
     StringBuilder sb = new StringBuilder(Math.Max(260, 2 * combined.Length)); 
     PathCanonicalize(sb, combined); 
     return sb.ToString(); 
    } 

    [DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern bool PathCanonicalize([Out] StringBuilder dst, string src); 

Una tercera estrategia consiste en engañar al CLR. Path.GetFullPath() funciona bien en un camino ficticio, así que asegúrese de darle siempre uno. Lo que puede hacer es cambiar la raíz con una ruta UNC falsa, llame GetFullPath(), y luego cambiar el real de vuelta en advertencia:. Esto puede requerir una venta dura en la revisión de código

public static string PathCombineAndCanonicalize3(string path1, string path2) 
    { 
     string originalRoot = string.Empty; 

     if (Path.IsPathRooted(path1)) 
     { 
      originalRoot = Path.GetPathRoot(path1); 
      path1 = path1.Substring(originalRoot.Length); 
     } 

     string fakeRoot = @"\\thiscantbe\real\"; 
     string combined = Path.Combine(fakeRoot, path1, path2); 
     combined = Path.GetFullPath(combined); 
     combined = combined.Substring(fakeRoot.Length); 
     combined = Path.Combine(originalRoot, combined); 
     return combined; 
    }