Existe-t-il une méthode pour vérifier si le chemin donné est le chemin complet? En ce moment, je fais cela:
if (template.Contains(":\\")) //full path already given
{
}
else //calculate the path from local Assembly
{
}
Mais il doit y avoir un moyen plus élégant de vérifier cela?
Essayez d'utiliser System.IO.Path.IsPathRooted
? Il renvoie également true
pour les chemins absolus.
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"
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
La condition ci-dessus:
false
dans la plupart des cas où le format de path
n'est pas valide (plutôt que de lever une exception)true
uniquement si path
inclut le volumeDans des scénarios comme celui que le PO a posé, il peut donc être plus approprié que les conditions des réponses précédentes. Contrairement à la condition ci-dessus:
path == System.IO.Path.GetFullPath(path)
lève des exceptions plutôt que de renvoyer false
dans ces scénarios: System.IO.Path.IsPathRooted(path)
renvoie true
si path
commence par un seul séparateur de répertoire.Enfin, voici une méthode qui encapsule la condition ci-dessus et exclut également les exceptions possibles 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 a fait un bon commentaire et réponse alternative adressant le cas curieux de chemins comme C:
Et C:dir
. Pour vous aider à décider de la manière dont vous souhaitez gérer ces chemins, vous pouvez approfondir MSDN -> Applications de bureau Windows -> Développer -> Technologies de bureau -> Accès et stockage des données -> Systèmes de fichiers locaux -> Gestion des fichiers -> À propos de la gestion des fichiers -> Création, Suppression et maintenance de fichiers -> Nommage des fichiers, des chemins et des espaces de noms -> Entièrement Chemins qualifiés contre chemins relatifs
Pour les fonctions API Windows qui manipulent les fichiers, les noms de fichiers peuvent souvent être relatifs au répertoire actuel, tandis que certaines API nécessitent un chemin d'accès complet. Un nom de fichier est relatif au répertoire actuel s'il ne commence pas par l'un des éléments suivants:
- Un nom UNC de n'importe quel format, qui commence toujours par deux barres obliques inverses ("\"). Pour plus d'informations, consultez la section suivante.
- Un indicateur de disque avec une barre oblique inverse, par exemple "C: \" ou "d: \".
- Une barre oblique inverse unique, par exemple, "\ répertoire" ou "\ fichier.txt". Ceci est également appelé chemin absolu.
Si un nom de fichier commence par un seul indicateur de disque mais pas la barre oblique inverse après les deux-points, il est interprété comme un chemin d'accès relatif au répertoire en cours sur le lecteur avec la lettre spécifiée. Notez que le répertoire actuel peut être ou non le répertoire racine en fonction de ce qu'il a été défini lors de la dernière opération de "changement de répertoire" sur ce disque. Voici des exemples de ce format:
- "C: tmp.txt" fait référence à un fichier nommé "tmp.txt" dans le répertoire en cours sur le lecteur C.
- "C: tempdir\tmp.txt" fait référence à un fichier dans un sous-répertoire du répertoire en cours sur le lecteur C.
[...]
Essayer
System.IO.Path.IsPathRooted(template)
Fonctionne pour les chemins UNC ainsi que les chemins locaux.
Par exemple.
Path.IsPathRooted(@"\\MyServer\MyShare\MyDirectory") // returns true
Path.IsPathRooted(@"C:\\MyDirectory") // returns true
Vieille question, mais une réponse de plus applicable. Si vous devez vous assurer que le volume est inclus dans un chemin local, vous pouvez utiliser System.IO.Path.GetFullPath () comme ceci:
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
}
En s'appuyant sur la réponse de weir: cela ne lance pas pour les chemins invalides, mais renvoie également false
pour les chemins comme "C:", "C: dirname" et "\ 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
}
Notez que cela renvoie des résultats différents sur Windows et Linux, par exemple "/ path" est absolu sous Linux, mais pas sous Windows.
Test de l'unité:
[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);
}
}
Pour vérifier si un chemin est entièrement qualifié (MSDN) :
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
C'est un peu plus simple que ce qui a déjà été proposé, et il retourne toujours false pour les chemins relatifs au lecteur comme C:foo
. Sa logique est directement basée sur la définition MSDN de "pleinement qualifié", et je n'ai trouvé aucun exemple sur lequel il se comporte mal.
Fait intéressant cependant, .NET Core 2.1 semble avoir une nouvelle méthode Path.IsPathFullyQualified
qui utilise une méthode interne PathInternal.IsPartiallyQualified
(emplacement du lien exact au 17/04/2018).
Pour la postérité et une meilleure maîtrise de ce post, voici l'implémentation de ce dernier pour référence:
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]));
}
C'est la solution que j'utilise
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
Cela fonctionne de la manière suivante:
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
Je ne suis pas vraiment sûr de ce que vous entendez par chemin complet (bien qu'en supposant dans l'exemple que vous voulez dire non relatif depuis la racine), eh bien, vous peut utiliser la classe Path pour vous aider à travailler avec les chemins physiques du système de fichiers, qui devraient vous couvrir pour la plupart des éventualités.