2009-03-08 3 views
8

Что равнозначно PathCanonicalize в C#?PathCanonicalize эквивалент в C#

Использование: Мне нужно хорошо подумать, ссылаются ли два пути к одному файлу (без доступа к диску). Мой типичный подход бросает его через несколько фильтров, таких как MakeAbsolute и PathCanonicalize, а затем делает сравнение без учета регистра.

ответ

12

быстро и грязно:

В прошлом я создал FileInfo объект из строки пути, а затем использовали свойство FullName. Это удаляет все .. и s.

Конечно, вы могли бы Interop:

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

3 решения:

лучший сценарий, где вы на 100% уверены, то вызывающий процесс будет иметь полный доступ к файловой системе. CAVEAT: разрешение на коробке производства может быть сложно

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

Но мы не всегда свободны. Часто вам нужно выполнить строчную арифметику без разрешения. Для этого есть естественный призыв. CAVEAT: прибегает к нативной вызову

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

Третья стратегия обмануть CLR. Path.GetFullPath() отлично работает на фиктивном пути, поэтому просто убедитесь, что вы всегда даете ему один. Что вы можете сделать, это поменять корень с фальшивым путем UNC, позвоните GetFullPath(), а затем поменять реальную обратно в CAVEAT:. это может потребовать трудно продать в обзоре кода

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