Pregunta Verifica si se da la ruta completa


¿Hay un método para verificar si la ruta dada es ruta completa? En este momento estoy haciendo esto:

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

Pero debe haber una manera más elegante para verificar esto?


75
2018-04-06 10:41


origen


Respuestas:


Intenta usar System.IO.Path.IsPathRooted? También regresa true para caminos absolutos

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"

109
2018-04-06 10:43



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

La condición anterior:

  • no requiere permisos del sistema de archivos
  • devoluciones false en la mayoría de los casos, donde el formato de path no es válido (en lugar de arrojar una excepción)
  • devoluciones true sólo si path incluye el volumen

En escenarios como el que planteó OP, puede ser más adecuado que las condiciones en las respuestas anteriores. A diferencia de la condición anterior:

  • path == System.IO.Path.GetFullPath(path) arroja excepciones en lugar de regresar false en estos escenarios:
    • La persona que llama no tiene los permisos requeridos
    • El sistema no pudo recuperar la ruta absoluta
    • ruta contiene dos puntos (":") que no forman parte de un identificador de volumen
    • La ruta especificada, el nombre del archivo o ambos exceden la longitud máxima definida por el sistema
  • System.IO.Path.IsPathRooted(path) devoluciones true Si path comienza con un único separador de directorio.

Finalmente, aquí hay un método que ajusta la condición anterior y también excluye las posibles excepciones restantes:

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 hizo un buen comentario y respuesta alternativa abordar el curioso caso de rutas como C: y C:dir. Para ayudar a decidir cómo puede manejar tales rutas, puede realizar una inmersión profunda en MSDN -> Aplicaciones de escritorio de Windows -> Desarrollar -> Tecnologías de escritorio -> Acceso a datos y almacenamiento -> Sistemas de archivos locales -> Gestión de archivos -> Acerca de la administración de archivos -> Crear, eliminar y mantener archivos -> Nombrar archivos, rutas y espacios de nombres -> Totalmente calificado vs. caminos relativos

Para las funciones de API de Windows que manipulan archivos, los nombres de archivos a menudo   ser relativo al directorio actual, mientras que algunas API requieren un completo   ruta calificada. Un nombre de archivo es relativo al directorio actual si   no comienza con uno de los siguientes:

  • Un nombre UNC de cualquier formato, que siempre comienza con dos caracteres de barra invertida ("\"). Para obtener más información, consulte la siguiente sección.
  • Un designador de disco con una barra diagonal inversa, por ejemplo "C: \" o "d: \".
  • Una barra invertida única, por ejemplo, "\ directorio" o "\ archivo.txt". Esto también se conoce como una ruta absoluta.

Si un nombre de archivo comienza con solo un designador de disco pero no el   barra invertida después de los dos puntos, se interpreta como una ruta relativa al   directorio actual en el disco con la letra especificada. Tenga en cuenta que   el directorio actual puede o no ser el directorio raíz dependiendo   en lo que se estableció durante el "directorio de cambio" más reciente   operación en ese disco. Ejemplos de este formato son los siguientes:

  • "C: tmp.txt" hace referencia a un archivo llamado "tmp.txt" en el directorio actual de la unidad C.
  • "C: tempdir \ tmp.txt" hace referencia a un archivo en un subdirectorio al directorio actual en la unidad C.

[...]


16
2018-01-27 19:34



Tratar

System.IO.Path.IsPathRooted(template)

Funciona tanto para rutas UNC como locales.

P.ej.

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

14
2018-04-06 10:45



Pregunta anterior, pero una respuesta más aplicable. Si necesita asegurarse de que el volumen esté incluido en una ruta de acceso local, puede usar System.IO.Path.GetFullPath () de esta manera:

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
}

10
2017-09-19 12:34



Sobre la base de presaLa respuesta de este: esto no arroja caminos inválidos, sino que también regresa false para rutas como "C:", "C: dirname" y "\ 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
}

Tenga en cuenta que esto arroja resultados diferentes en Windows y Linux, p. "/ ruta" es absoluta en Linux, pero no en Windows.

Prueba de unidad:

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

4
2017-11-30 09:24



No estoy muy seguro de lo que quieres decir con ruta completa (aunque asumiendo del ejemplo que quieres decir no relativo desde la raíz en adelante), bueno, puedes usar el Camino clase para ayudarlo a trabajar con las rutas físicas del sistema de archivos, lo que debería cubrirlo para la mayoría de las eventualidades.


0
2018-04-06 10:43



Esta es la solución que uso

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

Funciona de la siguiente manera:

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

0
2018-04-11 12:49



Para verificar si un camino es plenamente cualificado (MSDN):

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

Es un poco más simple de lo que ya se ha propuesto, y aún devuelve falso para rutas relativas a la unidad como C:foo. Su lógica se basa directamente en la definición de MSDN de "totalmente calificado", y no he encontrado ningún ejemplo en el que se comporte mal.


Curiosamente, sin embargo, .NET Core 2.1 parece tener un nuevo método Path.IsPathFullyQualified que usa un método interno PathInternal.IsPartiallyQualified (ubicación del enlace precisa a partir de 2018-04-17).

Para la posteridad y una mejor autocontención de esta publicación, aquí está la implementación de este último para referencia:

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

0
2018-04-17 16:47