2009-03-08 6 views
8

Qual è l'equivalente a PathCanonicalize in C#?PathCanonicalizza equivalente in C#

Utilizzo: È necessario valutare correttamente se due percorsi di file si riferiscono allo stesso file (senza accesso al disco). Il mio tipico approccio è stato quello di lanciarlo attraverso alcuni filtri come MakeAbsolute e PathCanonicalize, e quindi fare un confronto senza distinzione tra maiuscole e minuscole.

risposta

12

veloce e sporco:

In passato ho creato un oggetto FileInfo dalla stringa di percorso e poi utilizzato la proprietà FullName. Questo rimuove tutti i .. \ 's e i. \' S.

Naturalmente si potrebbe interoperabilità:

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

3 soluzioni:

Migliore delle ipotesi, in cui si è certi al 100% il processo chiamante avrà pieno accesso al file system. avvertimento: autorizzazione su una scatola di produzione può essere difficile

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

Ma, non siamo sempre liberi. Spesso è necessario eseguire l'aritmetica delle stringhe senza autorizzazione. C'è una chiamata nativa per questo. avvertimento: resort ad chiamata 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 terza strategia è quella di ingannare il CLR. Path.GetFullPath() funziona perfettamente su un percorso fittizio, quindi assicurati di dargli sempre uno. Che cosa si può fare è quello di scambiare la radice con un percorso UNC fasullo, chiamare GetFullPath(), e poi scambiare il vero uno indietro nel avvertimento:. questo può richiedere una vendita dura in revisione del codice

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