检查是不是给出完整路径

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' 对于相对路径(不一定是绝对路径)返回 true GetFullPath 访问文件系统并可能引发许多可能的异常。请参阅我的回答 (***.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() 也会给出错误值?

<input type='file'> for IE 给出完整路径,只需要文件名

cad完整路径改成相对路径改不了怎么办

为啥 cypress 无法识别我们是不是给出完整的类名