检查是否给出完整路径

时间:2011-04-06 10:41:36

标签: c# .net validation path

是否有方法检查给定路径是否为完整路径?现在我这样做:

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

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

9 个答案:

答案 0 :(得分:123)

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

答案 1 :(得分:24)

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

以上条件:

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

在OP提出的情况下,它可能比早期答案中的条件更合适。与上述条件不同:

  • path == System.IO.Path.GetFullPath(path)抛出异常而不是在这些场景中返回false
    • 来电者没有所需的权限
    • 系统无法检索绝对路径
    • 路径包含冒号(“:”),该冒号不是卷标识符的一部分
    • 指定的路径,文件名或两者都超出系统定义的最大长度
  • 如果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上当前目录中名为“tmp.txt”的文件。
  •   
  • “C:tempdir \ tmp.txt”是指驱动器C上当前目录的子目录中的文件。
  •   
     

[...]

答案 2 :(得分:15)

尝试

System.IO.Path.IsPathRooted(template)

适用于UNC路径以及本地路径。

E.g。

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

答案 3 :(得分:11)

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

答案 4 :(得分:7)

weir 的答案为基础:这不会引发无效路径,但也会为" C:"等路径返回false, " C:目录名"和" \ 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上返回不同的结果,例如&#34; /路径&#34;在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);
    }
}

答案 5 :(得分:4)

检查路径是否为fully qualified (MSDN)

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

它比已经提出的更简单,并且对于像C:foo这样的驱动器相对路径仍然返回false。它的逻辑直接基于MSDN对“完全限定”的定义,我没有发现任何错误的例子。

有趣的是,.NET Core 2.1似乎有一个新方法Path.IsPathFullyQualified,它使用内部方法PathInternal.IsPartiallyQualified(链接位置准确到2018-04-17)。

对于后人和本帖的更好的自我遏制,这里是后者的实施参考:

internal static bool IsPartiallyQualified(ReadOnlySpan<char> path)
{
    if (path.Length < 2)
    {
        // It isn't fixed, it must be relative.  There is no way to specify a fixed
        // path with one character (or less).
        return true;
    }

    if (IsDirectorySeparator(path[0]))
    {
        // There is no valid way to specify a relative path with two initial slashes or
        // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\
        return !(path[1] == '?' || IsDirectorySeparator(path[1]));
    }

    // The only way to specify a fixed path that doesn't begin with two slashes
    // is the drive, colon, slash format- i.e. C:\
    return !((path.Length >= 3)
        && (path[1] == VolumeSeparatorChar)
        && IsDirectorySeparator(path[2])
        // To match old behavior we'll check the drive character for validity as the path is technically
        // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
        && IsValidDriveChar(path[0]));
}

答案 6 :(得分:1)

这是我使用的解决方案

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

答案 7 :(得分:0)

我不确定完整路径的含义(虽然从示例中假设你是指从根开始的非亲属),你可以使用Path class,以帮助您使用物理文件系统路径,这应该涵盖大多数可能性。

答案 8 :(得分:0)

调用以下函数:

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

MSDN文档:Path.IsPathFullyQualified Method

MSDN文档中的有用引用如下:

  

此方法处理使用备用目录分隔符的路径。   假设根目录路径是一个常见错误   (IsPathRooted(String))不是相对的。例如,“ C:a”是驱动器   相对的,即针对C的当前目录进行解析:   (已扎根,但相对)。 “ C:\ a”植根而不是相对,也就是说,   当前目录不用于修改路径。