1. ホーム
  2. c#

C#で(ディレクトリ)パスを比較するには?

2023-08-06 03:41:13

質問

もし私が2つの DirectoryInfo オブジェクトがある場合、意味的に同じかどうかを比較するにはどうしたらよいでしょうか。 例えば、次のようなパスはすべて C:\temp :

  • C:\temp
  • C:\temp\
  • C:\temp\.
  • C:\temp\x\..\..\temp\.

と等しい場合もあれば、そうでない場合もあります。 C:\temp :

  • \temp 現在の作業ディレクトリがドライブ C:\
  • temp もし、現在の作業ディレクトリが C:\
  • C:\temp.
  • C:\temp...\

もし、現在の作業ディレクトリを考慮することが重要であれば、私は自分でそれを把握することができるので、それはそれほど重要ではありません。 しかし、unix ではドットは除去されないので、mono の下では別の結果を期待することになります。

大文字と小文字の区別は任意です。 パスは は存在するかしないか で、ユーザが に対するパーミッションがあるかどうか。 - 私はどんなI/Oも必要としない(だからパーミッションチェックもない)高速で堅牢な方法を好みますが、もし何かが組み込まれているなら、私は何でも満足です "good enough" も...。

私は、I/O なしでは、ある中間ストレージ層が同じストレージを同じファイルにたまたまマッピングしたかどうかを判断することができないことを理解しています (そして、I/O があっても、物事が十分に混乱するときは、おそらく不可能です)。 つまり、ある種のファイルシステム上で、同じファイル(存在する場合)へ必然的に解決されるようなパスです。 (B) I/O は時々問題となる副作用を引き起こし、(C) 他のさまざまなソフトウェア コンポーネントは時々提供されたパスを混乱させ、同等のパスの最も一般的な変換に影響を受けない方法で比較できることは有用であり、最後に (D) 展開の準備として事前にいくつかのサニティ チェックを行うことは有用ですが、これらは展開予定のシステムがアクセスする前に行われます。

どのように解決するのか?

から この回答 から、この方法はいくつかのエッジケースを処理することができます。

public static string NormalizePath(string path)
{
    return Path.GetFullPath(new Uri(path).LocalPath)
               .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
               .ToUpperInvariant();
}

詳しくは元の回答にあります。のように呼んでください。

bool pathsEqual = NormalizePath(path1) == NormalizePath(path2);

ファイルパスとディレクトリパスの両方で動作するはずです。