Check if full path given

是否有一个方法来检查给定的路径是否是完整路径? 现在我正在这样做:

if (template.Contains(":\\")) //full path already given
{
}
else //calculate the path from local assembly
{
}

但是一定有更优雅的方法来检查这个?

62421 次浏览

尝试使用 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"

I'm not really sure what you mean by 全路径 (though assuming from the example you mean non-relative from the root onwards), well, you can use the 路径 class to aid you in working with physical filesystem paths, which should cover you for most eventualities.

试试看

System.IO.Path.IsPathRooted(template)

适用于 UNC 路径和本地路径。

E.g.

Path.IsPathRooted(@"\\MyServer\MyShare\MyDirectory")  // returns true
Path.IsPathRooted(@"C:\\MyDirectory")  // returns true

Old question, but one more applicable answer. If you need to ensure the volume is included in a local path, you can use System.IO.Path.GetFullPath() like this:

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
}
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)

以上条件:

  • 不需要文件系统权限
  • 在大多数 path格式无效的情况下返回 false(而不是抛出异常)
  • 仅当 path包含卷时返回 true

In scenarios like the one the OP posed, it may therefore be more suitable than the conditions in the earlier answers. Unlike the above condition:

  • 在这些场景中,path == System.IO.Path.GetFullPath(path)抛出异常而不是返回 false:
    • 调用方没有所需的权限
    • 系统无法检索绝对路径
    • Path 包含不属于卷标识符的冒号(“ :”)
    • 指定的路径、文件名或两者都超过系统定义的最大长度
  • System.IO.Path.IsPathRooted(path) returns true if path begins with a single directory separator.

最后,这里有一个方法可以包装上面的条件,并且排除其余可能的异常:

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 桌面应用程序—— > 冲洗—— > 桌面技术—— > 数据存取及储存—— > 本地文件系统—— > 文件管理—— > About File Management—— > C:dir0—— > C:dir1—— > C:dir2

For Windows API functions that manipulate files, file names can often 相对于工作目录,而有些 API 则需要一个完全 qualified path. A file name is relative to the current directory if it does not begin with one of the following:

  • 任何格式的 UNC 名称,总是以两个反斜杠字符(“”)开头。有关更多信息,请参见下一节。
  • 带有反斜杠的磁盘指示符,例如“ C:”或“ d:”。
  • 一个反斜杠,例如,“目录”或“ file.txt”。这也被称为绝对路径。

如果文件名仅以磁盘指示符开头,而不以 后面的反斜杠,它被解释为到 current directory on the drive with the specified letter. Note that 工作目录可能是根目录,也可能不是 在最近的“更改目录”中设置为什么 operation on that disk. Examples of this format are as follows:

  • “ c: tmp.txt”指的是驱动器 C 的工作目录中名为“ tmp.txt”的文件。
  • “ c: temdir tmp.txt”指的是驱动器 c 上工作目录的子目录中的一个文件。

[...]

Building on 's answer: this does not throw for invalid paths, but also returns false for paths like "C:", "C:dirname" and "\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
}

Note that this returns different results on Windows and Linux, e.g. "/path" is absolute on Linux, but not on Windows.

Unit test:

[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); // technically, a valid filename on Linux


// Invalid on Windows, valid (but not full paths) on Linux
TryIsFullPath(@"C:\inval|d", false, !isWindows);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname", false, !isWindows);
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);
}
}

这是我使用的解决方案

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

在.NET Core 2.1 + 和.NET 上

You can use Path.IsPathFullyQualified (来源).

在.NET 框架上

您可以实现 < em > 完全符合资格 (微软文件)的定义。例如(在 Windows 上) :

public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\") && root != @"\";
}

Note the guard against being rooted only by directory and not also by drive. See Path.IsPathFullyQualified备注 for more explanation.

As of .NET Core 2.1/NET Standard 2.1, you can call the following method:

Path.IsPathFullyQualified(@"c:\foo")

MSDN doc: IsPathFully 限定方法

The useful cite from MSDN doc follows:

此方法处理使用备用目录分隔符的路径。 假设根路径是一种常见的错误 (IsPathRooted (String))不是相对的。例如,“ C: a”是驱动器 相对的,也就是说,它是根据 C 的工作目录解决的: “ C: a”是有根的,而不是相对的,也就是说, the current directory isn't used to modify the path.