Réponses:
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"
IsPathRooted
: éviter d'accéder au système de fichiers ou de lever des exceptions pour une entrée invalide.
IsPathRooted
, ce n'était certainement rien de significatif. La GetFullPath
ligne a été incluse afin que le chemin en cours d'évaluation puisse être observé
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 proposé par le PO, 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 revenir 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 englobe 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 une réponse alternative abordant le cas curieux des chemins comme C:
et C:dir
. Pour vous aider à décider de la manière dont vous souhaitez gérer ces chemins, vous voudrez peut-être vous plonger dans MSDN -> Applications de bureau Windows -> Développer -> Technologies de bureau -> Accès aux données et stockage -> Systèmes de fichiers locaux - -> Gestion des fichiers -> À propos de la gestion des fichiers -> Création, suppression et maintenance de fichiers -> Nommer des fichiers, des chemins et des espaces de noms -> Chemins complets ou relatifs
Pour les fonctions d'API Windows qui manipulent des fichiers, les noms de fichiers peuvent souvent être relatifs au répertoire en cours, tandis que certaines API nécessitent un chemin 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 inversées ("\"). Pour plus d'informations, consultez la section suivante.
- Un indicateur de disque avec une barre oblique inverse, par exemple "C: \" ou "d: \".
- Une seule barre oblique inverse, par exemple, "\ directory" ou "\ file.txt". Ceci est également appelé chemin absolu.
Si un nom de fichier commence par un seul identificateur de disque mais pas par la barre oblique inverse après les deux points, il est interprété comme un chemin relatif vers le répertoire actuel sur le lecteur avec la lettre spécifiée. Notez que le répertoire en cours peut ou non être 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. Des exemples de ce format sont les suivants:
- «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 actuel sur le lecteur C.
[...]
Ancienne question, mais une autre réponse 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
}
GetFullPath
accède au système de fichiers et peut lever un certain nombre d'exceptions possibles. Voir ma réponse ( stackoverflow.com/a/35046453/704808 ) pour une alternative qui assure toujours un chemin complet.
Construire sur déversoir de réponse « : cela ne jette pas pour les chemins invalides, mais aussi des retours false
pour les chemins comme « C: », « C: dirname » et « \ chemin ».
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 sous 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 pleinement 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 renvoie toujours false pour les chemins relatifs aux lecteurs comme C:foo
. Sa logique est basée directement 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 internePathInternal.IsPartiallyQualified
(emplacement du lien précis à partir du 17/04/2018).
Pour la postérité et une meilleure maîtrise de soi de cet article, voici la mise en œuvre 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
C:\foo\..\foo
ouC:\foo\.\.\.
Appelez la fonction suivante:
Path.IsPathFullyQualified(@"c:\foo")
MSDN doc: méthode Path.IsPathFullyQualified
La citation utile de MSDN doc suit:
Cette méthode gère les chemins qui utilisent le séparateur de répertoire alternatif. C'est une erreur fréquente de supposer que les chemins enracinés ( IsPathRooted (String) ) ne sont pas relatifs. Par exemple, "C: a" est relatif au lecteur, c'est-à-dire qu'il est résolu par rapport au répertoire courant pour C: (enraciné, mais relatif). "C: \ a" est rooté et non relatif, c'est-à-dire que le répertoire courant n'est pas utilisé pour modifier le chemin.
Je ne suis pas vraiment sûr de ce que vous entendez par chemin complet (bien qu'en supposant à partir de l'exemple que vous vouliez dire non relatif à partir de la racine), eh bien, vous pouvez utiliser la classe Path pour vous aider à travailler avec des chemins de système de fichiers physiques, ce qui devrait couvrir vous pour la plupart des éventualités.