2011-04-06 111 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

相關問題