2011-04-06 197 views
68

有没有一种方法来检查给定路径是否是完整路径?现在我这样做:检查是否给出完整路径

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

但是,必须有更优雅的方式来检查这一点?

回答

102

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

为什么第二个例子是绝对路径? – om471987 2012-04-04 00:59:35

+1

第二条道路不是绝对的,但它是根深蒂固的。首斜杠表示系统的根。 – detaylor 2012-04-04 07:48:47

+1

@SmirkinGherkin那么根系和绝对路径有什么区别? – 2013-03-01 01:23:59

0

我真的不知道你所说的完整路径是什么意思(尽管从你的意思是从根开始非亲属的例子假设),那么,你可以使用Path类来帮助你使用物理文件系统路径,这些路径应该涵盖大多数事件。

14

尝试

System.IO.Path.IsPathRooted(template) 

Works的UNC路径,以及本地的。

E.g.

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

Thnx,但Smirkin是第一个,并且只能接受一个回答(: – hs2d 2011-04-06 10:47:11

10

老问题,但还有一个适用的答案。如果您需要确保该卷包含在本地路径,你可以使用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 
} 
+3

这就是我所需要的,并且自IsPathRooted'返回true后似乎更接近原始问题对于相对路径(不一定是绝对路径) – bitcoder 2015-12-07 20:37:56

+0

'GetFullPath'访问文件系统并可能抛出一些可能的异常。请参阅我的答案(http://stackoverflow.com/a/35046453/704808)一个完整的路径 – weir 2016-01-27 20:49:30

11
Path.IsPathRooted(path) 
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) 

上述条件:

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

在像OP构成的一个场景中,因此可能比在较早的答案的条件更适合。不同于上述条件:

  • path == System.IO.Path.GetFullPath(path)抛出异常,而不是在这些情况下返回false
    • 调用方没有所需的权限
    • 系统无法获取绝对路径
    • path包含不是卷标识符的一部分的冒号(“:”)
    • 指定的路径,文件名,或两者都超出了系统定义的最大长度
  • 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取得了良好的意见和alternative answer解决路径好奇的情况下,像C:C:dir。为了帮助决定你可能希望如何处理这样的路径,你可能要采取深潜到MSDN - >Windows桌面应用程序 - >开发 - >桌面技术 - >数据访问和存储 - >的本地文件系统 - >文件管理 - >关于文件管理 - >创建,删除和维护文件 - >命名文件,路径和命名空间 - >Fully Qualified vs. Relative Paths

对于处理文件的Windows API函数,文件名通常可以是 相对于当前目录,而某些API则需要完整的 限定路径。

  • 任何格式,它总是以两个反斜杠字符(“\”)开始的UNC名称:如果 不与下面的一个开头的文件名是相对于当前目录。有关更多信息,请参阅下一节。
  • 带反斜杠的磁盘指示符,例如“C:\”或“d:\”。
  • 单个反斜杠,例如“\ directory”或“\ file.txt”。这也被称为绝对路径。

如果一个文件名,只有一个磁盘代号开始而不是冒号后的 反斜杠,它被解释为与指定字母驱动器上的 当前目录的相对路径。请注意, 当前目录可能是也可能不是根目录,具体取决于 它在该磁盘上最近的“更改目录” 操作期间的设置。此格式的实例如下:

  • “C:tmp.txt” 是指在驱动器C.当前目录
  • “C名为 “tmp.txt” 文件:TEMPDIR \ tmp.txt “指的是文件中的一个子目录到当前目录的驱动器C.

[...]

+2

我喜欢这不会导致无效路径,但它会返回true,例如“C:”和“C:dir”,这些路径由GetFullPath使用当前目录解析(所以它们不是绝对)。发表一个答案,返回false这些。 – EM0 2017-11-30 09:26:22

+0

@ EM0 - 谢谢!你刚刚教了我一些东西。:) – weir 2017-12-07 20:49:58

1

大厦的回答是:这并不抛出无效的路径,但也返回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; 

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

     return !(pathRoot == path && pathRoot.StartsWith("\\\\") && pathRoot.IndexOf('\\', 2) == -1); // A UNC server name without a share name (e.g "\\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); 
    } 

    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); 
     } 
    } 
+0

好东西。我确实注意到https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths指出,在Windows上,路径是* not * relative if它以*'单个反斜杠开始,例如“\ directory”或“\ file.txt”。这也被称为绝对路径。'* – weir 2017-12-07 21:17:28

+1

好点!看起来我的术语已关闭。当我说“绝对路径”时,我真的在想MS叫做“完整路径”。我更改了名称并为此添加了一个测试用例。 – EM0 2017-12-09 21:25:27

相关问题