检查是不是给出完整路径
Posted
技术标签:
【中文标题】检查是不是给出完整路径【英文标题】:Check if full path given检查是否给出完整路径 【发布时间】:2011-07-30 17:14:16 【问题描述】:有没有办法检查给定路径是否为完整路径?现在我正在这样做:
if (template.Contains(":\\")) //full path already given
else //calculate the path from local assembly
但是必须有更优雅的方法来检查这个?
【问题讨论】:
【参考方案1】:尝试使用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"
【讨论】:
第二个例子怎么是绝对路径? 第二条路径不是绝对的,但它是有根的。前导斜杠表示系统的根目录。 @SmirkinGherkin 那么根路径和绝对路径有什么区别? 根据documentation '测试给定路径是否包含根。如果路径以反斜杠 ("\") 或驱动器号和冒号 (":") 开头,则该路径被认为是根路径。所以没有解释区别,而是术语。 查看我的回答 (***.com/a/35046453/704808) 以获取在保留IsPathRooted
优势的同时确保完整路径的替代方案:避免访问文件系统或为无效输入引发异常。【参考方案2】:
我不太确定您所说的 完整路径 是什么意思(尽管从示例中假设您的意思是从根开始非相对),那么您可以使用 Path 类帮助您处理物理文件系统路径,这应该涵盖大多数情况。
【讨论】:
【参考方案3】:试试
System.IO.Path.IsPathRooted(template)
适用于 UNC 路径以及本地路径。
例如
Path.IsPathRooted(@"\\MyServer\MyShare\MyDirectory") // returns true
Path.IsPathRooted(@"C:\\MyDirectory") // returns true
【讨论】:
【参考方案4】:老问题,但更适用的答案。如果需要确保卷包含在本地路径中,可以像这样使用 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
【讨论】:
这是我需要的,并且似乎更接近原始问题,因为 IsPathRooted' 对于相对路径(不一定是绝对路径)返回 trueGetFullPath
访问文件系统并可能引发许多可能的异常。请参阅我的回答 (***.com/a/35046453/704808) 以获取仍然确保完整路径的替代方案。【参考方案5】:
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
以上条件:
不需要文件系统权限 在path
的格式无效(而不是抛出异常)的大多数情况下返回false
仅当path
包含卷时才返回true
在像 OP 提出的场景中,因此它可能比早期答案中的条件更合适。与上述情况不同:
path == System.IO.Path.GetFullPath(path)
在这些情况下抛出异常而不是返回 false
:
调用者没有所需的权限
系统无法检索到绝对路径
路径包含不属于卷标识符的冒号 (":")
指定的路径、文件名或两者都超过了系统定义的最大长度
如果path
以单个目录分隔符开头,则System.IO.Path.IsPathRooted(path)
返回true
。
最后,这是一个包装上述条件并排除剩余可能异常的方法:
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盘当前目录下名为“tmp.txt”的文件。 “C:tempdir\tmp.txt”指的是驱动器 C 上当前目录的子目录中的文件。[...]
【讨论】:
我喜欢这不会抛出无效路径,但对于“C:”和“C:dir”等路径返回 true,这些路径由 GetFullPath 使用当前目录解析(因此它们'不是绝对的)。发布了一个返回 false 的答案。 @EM0 - 谢谢!你刚刚教会了我一些东西。 :)【参考方案6】:基于 weir 的回答:这不会抛出无效路径,但也会为“C:”、“C:dirname”和“\path”等路径返回 false
。
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.microsoft.com/en-us/library/windows/desktop/… 指出,在 Windows 上,如果路径以 ' 单个反斜杠开头,则它是 not 相对的,例如,“\directory”或“\file.txt”。这也称为绝对路径。' 好点!看起来我的术语已经关闭了。当我说“绝对路径”时,我真的在想 MS 所说的“完整路径”。我已经更改了名称并为此添加了一个测试用例。 感谢您的回答,它对我帮助很大。但是,请注意,对于 \\server\ 等 UNC 路径,该方法返回 true,但如果您随后调用 Directory.Exists(path) (System.ArgumentException: 'UNC 路径应采用以下形式,则会引发异常\\服务器\共享。') 很高兴看到人们仍在使用它并发现新的边缘案例@Carl 更新了代码并对此进行了测试!【参考方案7】:这是我使用的解决方案
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
or C:\foo\.\.\.
【参考方案8】:
在 .NET Core 2.1+ 和 .NET 上
您可以使用Path.IsFullyQualified (source)。
在 .NET 框架上
你可以实现fully qualified (MS Docs)的定义。例如:
public static bool IsPathFullyQualified(string path)
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
【讨论】:
【参考方案9】:从 .NET Core 2.1/NET Standard 2.1 开始,您可以调用以下方法:
Path.IsPathFullyQualified(@"c:\foo")
MSDN 文档:Path.IsPathFullyQualified Method
来自 MSDN 文档的有用引用如下:
此方法处理使用备用目录分隔符的路径。 假设有根路径是一个常见的错误 (IsPathRooted(String)) 不是相对的。例如,“C:a”是驱动器 相对的,也就是说,它是针对 C 的当前目录解析的: (有根,但相对)。 "C:\a" 是有根的而不是相对的,也就是说, 当前目录不用于修改路径。
【讨论】:
以上是关于检查是不是给出完整路径的主要内容,如果未能解决你的问题,请参考以下文章
检查appdata中是不是存在文件而不在python代码中添加完整路径
log4j 漏洞检查:如何快速检测是不是在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片
Java:为啥即使路径完整,使用 file.exists() 也会给出错误值?