2009-03-08 10 views
8

C#でPathCanonicalizeと同等の機能はありますか?PathCanonicalizeはC#で同等です

使用方法:2つのファイルパスが同じファイル(ディスクアクセスなし)を参照しているかどうかを確認する必要があります。私の典型的なアプローチは、MakeAbsoluteやPathCanonicalizeのようないくつかのフィルターを通してそれを投げて、大文字小文字を区別しない比較をしています。

答えて

12

間に合わせ:

過去には、私はパス文字列からFileInfoオブジェクトを作成し、FullNameプロパティを使用していました。これは..と\のすべてを削除します。

もちろん、あなたは、相互運用可能性:

[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; 
    } 
を押し売りが必要な場合があります