回答:
使用してみSystem.IO.Path.IsPathRooted
ますか?true
絶対パスの場合も戻ります。
System.IO.Path.IsPathRooted(@"c:\foo"); // true
System.IO.Path.IsPathRooted(@"\foo"); // true
System.IO.Path.IsPathRooted("foo"); // false
System.IO.Path.IsPathRooted(@"c:1\foo"); // surprisingly also true
System.IO.Path.GetFullPath(@"c:1\foo");// returns "[current working directory]\1\foo"
IsPathRooted
。
IsPathRooted
重要なものではありませんでした。GetFullPath
ラインは、パスを観察することができ、評価されるように含まれていた
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
上記の条件:
false
の形式path
が無効なほとんどの場合に(例外をスローするのではなく)を返します。true
場合path
にのみ返されますしたがって、OPが提示したようなシナリオでは、以前の回答の条件よりも適している可能性があります。上記の条件とは異なり:
path == System.IO.Path.GetFullPath(path)
false
これらのシナリオで戻るのではなく、例外をスローします。
System.IO.Path.IsPathRooted(path)
単一のディレクトリ区切り文字で始まるtrue
場合に返されますpath
。最後に、上記の条件をラップし、残りの可能な例外を排除するメソッドを次に示します。
public static bool IsFullPath(string path) {
return !String.IsNullOrWhiteSpace(path)
&& path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1
&& Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal);
}
編集:EM0は、やのようなパスの奇妙なケースに対処する優れたコメントと代替回答をC:
行いましたC:dir
。このようなパスの処理方法を決定するには、MSDN-> Windowsデスクトップアプリケーション -> 開発 -> デスクトップテクノロジー -> データアクセスとストレージ -> ローカルファイルシステム - - > [ ファイル管理 ] - > [ ファイル管理について - > 、削除を作成し、ファイルの維持 - > ファイル、パス、および名前空間の命名 - > 完全修飾対相対パス
ファイルを操作するWindows API関数の場合、一部のAPIには完全修飾パスが必要ですが、ファイル名は多くの場合、現在のディレクトリを基準にしています。ファイル名が次のいずれかで始まらない場合、ファイル名は現在のディレクトリを基準にしています。
- 常に2つのバックスラッシュ文字( "\")で始まる任意の形式のUNC名。詳細については、次のセクションを参照してください。
- 「C:\」や「d:\」などのバックスラッシュ付きのディスク指定子。
- 単一のバックスラッシュ。たとえば、「\ directory」または「\ file.txt」。これは、絶対パスとも呼ばれます。
ファイル名がディスク指定子のみで始まり、コロンの後のバックスラッシュではない場合、指定された文字を含むドライブ上の現在のディレクトリへの相対パスとして解釈されます。現在のディレクトリがルートディレクトリである場合とそうでない場合があるのは、そのディスクでの最新の「ディレクトリの変更」操作中に設定された内容によって異なります。この形式の例は次のとおりです。
- 「C:tmp.txt」は、ドライブCの現在のディレクトリにある「tmp.txt」という名前のファイルを指します。
- 「C:tempdir \ tmp.txt」は、ドライブCの現在のディレクトリのサブディレクトリにあるファイルを指します。
[...]
古い質問ですが、もう1つ該当する答えがあります。ボリュームがローカルパスに含まれていることを確認する必要がある場合は、次のようにSystem.IO.Path.GetFullPath()を使用できます。
if (template == System.IO.Path.GetFullPath(template))
{
; //template is full path including volume or full UNC path
}
else
{
if (useCurrentPathAndVolume)
template = System.IO.Path.GetFullPath(template);
else
template = Assembly.GetExecutingAssembly().Location
}
GetFullPath
ファイルシステムにアクセスし、いくつかの例外をスローする可能性があります。フルパスを保証する別の方法については、私の回答(stackoverflow.com/a/35046453/704808)を参照してください。
weirの答えに基づいて構築すると、これは無効なパスに対してはスローされませんが、false
「C:」、「C:dirname」、「\ path」などのパスに対しても戻ります。
public static bool IsFullPath(string path)
{
if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path))
return false;
string pathRoot = Path.GetPathRoot(path);
if (pathRoot.Length <= 2 && pathRoot != "/") // Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X:, but accepts / to support Linux
return false;
if (pathRoot[0] != '\\' || pathRoot[1] != '\\')
return true; // Rooted and not a UNC path
return pathRoot.Trim('\\').IndexOf('\\') != -1; // A UNC server name without a share name (e.g "\\NAME" or "\\NAME\") is invalid
}
これはWindowsとLinuxでは異なる結果を返すことに注意してください。たとえば、「/ path」はLinuxでは絶対値ですが、Windowsでは絶対値ではありません。
単体テスト:
[Test]
public void IsFullPath()
{
bool isWindows = Environment.OSVersion.Platform.ToString().StartsWith("Win"); // .NET Framework
// bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows); // .NET Core
// These are full paths on Windows, but not on Linux
TryIsFullPath(@"C:\dir\file.ext", isWindows);
TryIsFullPath(@"C:\dir\", isWindows);
TryIsFullPath(@"C:\dir", isWindows);
TryIsFullPath(@"C:\", isWindows);
TryIsFullPath(@"\\unc\share\dir\file.ext", isWindows);
TryIsFullPath(@"\\unc\share", isWindows);
// These are full paths on Linux, but not on Windows
TryIsFullPath(@"/some/file", !isWindows);
TryIsFullPath(@"/dir", !isWindows);
TryIsFullPath(@"/", !isWindows);
// Not full paths on either Windows or Linux
TryIsFullPath(@"file.ext", false);
TryIsFullPath(@"dir\file.ext", false);
TryIsFullPath(@"\dir\file.ext", false);
TryIsFullPath(@"C:", false);
TryIsFullPath(@"C:dir\file.ext", false);
TryIsFullPath(@"\dir", false); // An "absolute", but not "full" path
// Invalid on both Windows and Linux
TryIsFullPath(null, false, false);
TryIsFullPath("", false, false);
TryIsFullPath(" ", false, false);
TryIsFullPath(@"C:\inval|d", false, false);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname", false, false);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname\", false, !isWindows);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname\\", false, !isWindows);
}
private static void TryIsFullPath(string path, bool expectedIsFull, bool expectedIsValid = true)
{
Assert.AreEqual(expectedIsFull, PathUtils.IsFullPath(path), "IsFullPath('" + path + "')");
if (expectedIsFull)
{
Assert.AreEqual(path, Path.GetFullPath(path));
}
else if (expectedIsValid)
{
Assert.AreNotEqual(path, Path.GetFullPath(path));
}
else
{
Assert.That(() => Path.GetFullPath(path), Throws.Exception);
}
}
パスが完全修飾(MSDN)かどうかを確認するには:
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
これは、すでに提案されているものよりも少し単純ですが、などのドライブ相対パスに対しては依然としてfalseを返しますC:foo
。そのロジックは「完全修飾」のMSDN定義に直接基づいており、私はそれが正しく動作しない例を見つけていません。
ただし、興味深いことに、.NET Core 2.1 Path.IsPathFullyQualified
には、内部メソッドを使用する新しいメソッドがあるようです。PathInternal.IsPartiallyQualified
(2018-04-17現在のリンクの場所は正確です)。
この投稿の子孫とより良い自己完結性のために、参考のために後者の実装を以下に示します。
internal static bool IsPartiallyQualified(ReadOnlySpan<char> path)
{
if (path.Length < 2)
{
// It isn't fixed, it must be relative. There is no way to specify a fixed
// path with one character (or less).
return true;
}
if (IsDirectorySeparator(path[0]))
{
// There is no valid way to specify a relative path with two initial slashes or
// \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\
return !(path[1] == '?' || IsDirectorySeparator(path[1]));
}
// The only way to specify a fixed path that doesn't begin with two slashes
// is the drive, colon, slash format- i.e. C:\
return !((path.Length >= 3)
&& (path[1] == VolumeSeparatorChar)
&& IsDirectorySeparator(path[2])
// To match old behavior we'll check the drive character for validity as the path is technically
// not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
&& IsValidDriveChar(path[0]));
}
これは私が使用するソリューションです
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
次のように機能します。
IsFullPath(@"c:\foo"); // true
IsFullPath(@"C:\foo"); // true
IsFullPath(@"c:\foo\"); // true
IsFullPath(@"c:/foo"); // false
IsFullPath(@"\foo"); // false
IsFullPath(@"foo"); // false
IsFullPath(@"c:1\foo\"); // false
C:\foo\..\foo
またはC:\foo\.\.\.
次の関数を呼び出します。
Path.IsPathFullyQualified(@"c:\foo")
MSDN doc:Path.IsPathFullyQualifiedメソッド
MSDNドキュメントからの有用な引用は次のとおりです。
このメソッドは、代替ディレクトリ区切り記号を使用するパスを処理します。ルート化されたパス(IsPathRooted(String))が相対パスではないと仮定することはよくある間違いです。たとえば、「C:a」はドライブ相対です。つまり、C:の現在のディレクトリに対して解決されます(ルート付きですが、相対)。「C:\ a」はルートではなく、相対パスです。つまり、現在のディレクトリはパスの変更に使用されません。