Check if full path given

谁说我不能喝 提交于 2019-12-31 10:05:40

问题


Is there a method to check if given path is full path? Right now im doing this:

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

But there must be more elegant way for checking this?


回答1:


Try using System.IO.Path.IsPathRooted? It also returns true for absolute paths.

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"



回答2:


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

The above condition:

  • does not require file system permissions
  • returns false in most cases where the format of path is invalid (rather than throwing an exception)
  • returns true only if path includes the volume

In scenarios like the one the OP posed, it may therefore be more suitable than the conditions in the earlier answers. Unlike the above condition:

  • path == System.IO.Path.GetFullPath(path) throws exceptions rather than returning false in these scenarios:
    • The caller does not have the required permissions
    • The system could not retrieve the absolute path
    • path contains a colon (":") that is not part of a volume identifier
    • The specified path, file name, or both exceed the system-defined maximum length
  • System.IO.Path.IsPathRooted(path) returns true if path begins with a single directory separator.

Finally, here is a method that wraps the above condition and also forecloses the remaining possible exceptions:

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

EDIT: EM0 made a good comment and alternative answer addressing the curious case of paths like C: and C:dir. To help decide how you may want to handle such paths, you may want to take deep dive to MSDN --> Windows desktop applications --> Develop --> Desktop technologies --> Data Access and Storage --> Local File Systems --> File Management --> About File Management --> Creating, Deleting, and Maintaining Files --> Naming Files, Paths, and Namespaces --> Fully Qualified vs. Relative Paths

For Windows API functions that manipulate files, file names can often be relative to the current directory, while some APIs require a fully qualified path. A file name is relative to the current directory if it does not begin with one of the following:

  • A UNC name of any format, which always start with two backslash characters ("\"). For more information, see the next section.
  • A disk designator with a backslash, for example "C:\" or "d:\".
  • A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.

If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter. Note that the current directory may or may not be the root directory depending on what it was set to during the most recent "change directory" operation on that disk. Examples of this format are as follows:

  • "C:tmp.txt" refers to a file named "tmp.txt" in the current directory on drive C.
  • "C:tempdir\tmp.txt" refers to a file in a subdirectory to the current directory on drive C.

[...]




回答3:


Try

System.IO.Path.IsPathRooted(template)

Works for UNC paths as well as local ones.

E.g.

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



回答4:


Old question, but one more applicable answer. If you need to ensure the volume is included in a local path, you can use System.IO.Path.GetFullPath() like this:

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
}



回答5:


Building on weir's answer: this does not throw for invalid paths, but also returns false for paths like "C:", "C:dirname" and "\path".

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
}

Note that this returns different results on Windows and Linux, e.g. "/path" is absolute on Linux, but not on Windows.

Unit test:

[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);
    }
}



回答6:


To check whether a path is fully qualified (MSDN):

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

It's a bit simpler than what's already been proposed, and it still returns false for drive-relative paths like C:foo. Its logic is based directly on the MSDN definition of "fully qualified", and I haven't found any examples it misbehaves on.


Interestingly however, .NET Core 2.1 seems to have a new method Path.IsPathFullyQualified which uses an internal method PathInternal.IsPartiallyQualified (link location accurate as of 2018-04-17).

For posterity and better self-containment of this post, here's the latter's implementation for reference:

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]));
}



回答7:


This is the solution I use

public static bool IsFullPath(string path)
{
    try
    {
        return Path.GetFullPath(path) == path;
    }
    catch
    {
        return false;
    }
}

It works the following way:

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



回答8:


I'm not really sure what you mean by full path (though assuming from the example you mean non-relative from the root onwards), well, you can use the Path class to aid you in working with physical filesystem paths, which should cover you for most eventualities.




回答9:


Call the following function:

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

MSDN doc: Path.IsPathFullyQualified Method

The useful cite from MSDN doc follows:

This method handles paths that use the alternate directory separator. It's a frequent mistake to assume that rooted paths (IsPathRooted(String)) aren't relative. For example, "C:a" is drive relative, that is, it's resolved against the current directory for C: (rooted, but relative). "C:\a" is rooted and not relative, that is, the current directory isn't used to modify the path.



来源:https://stackoverflow.com/questions/5565029/check-if-full-path-given

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!