Risposte:
Prova a usare System.IO.Path.IsPathRooted
? Ritorna anche true
per percorsi assoluti.
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
: evitare l'accesso al file system o generare eccezioni per input non valido.
IsPathRooted
, di certo non era niente di significativo. La GetFullPath
linea è stata inclusa in modo che il percorso in corso di valutazione potesse essere osservato
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
La condizione di cui sopra:
false
nella maggior parte dei casi in cui il formato dipath
non è valido (anziché generare un'eccezione)true
solo se path
include il volumeIn scenari come quello proposto dal PO, potrebbe quindi essere più adatto rispetto alle condizioni delle risposte precedenti. A differenza della condizione di cui sopra:
path == System.IO.Path.GetFullPath(path)
genera eccezioni anziché restituire false
in questi scenari:
System.IO.Path.IsPathRooted(path)
restituisce true
se path
inizia con un singolo separatore di directory.Infine, ecco un metodo che avvolge la condizione di cui sopra e preclude anche le restanti possibili eccezioni:
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 ha fatto un buon commento e una risposta alternativa affrontando il curioso caso di percorsi come C:
e C:dir
. Per decidere come gestire tali percorsi, potresti voler approfondire MSDN -> Applicazioni desktop Windows -> Sviluppo -> Tecnologie desktop -> Accesso e archiviazione dati -> File system locali - -> Gestione file -> Informazioni sulla gestione dei file -> Creazione, eliminazione e manutenzione dei file -> Denominazione di file, percorsi e spazi dei nomi -> Percorsi completamente qualificati e relativi
Per le funzioni API di Windows che manipolano i file, i nomi dei file possono spesso essere relativi alla directory corrente, mentre alcune API richiedono un percorso completo. Un nome file è relativo alla directory corrente se non inizia con uno dei seguenti:
- Un nome UNC di qualsiasi formato, che inizia sempre con due caratteri barra rovesciata ("\"). Per ulteriori informazioni, vedere la sezione successiva.
- Un designatore di disco con una barra rovesciata, ad esempio "C: \" o "d: \".
- Una singola barra rovesciata, ad esempio "\ directory" o "\ file.txt". Viene anche definito percorso assoluto.
Se un nome file inizia solo con un designatore di disco ma non con la barra rovesciata dopo i due punti, viene interpretato come un percorso relativo alla directory corrente sull'unità con la lettera specificata. Notare che la directory corrente può essere o meno la directory root a seconda di cosa è stata impostata durante l'operazione di "modifica directory" più recente su quel disco. Esempi di questo formato sono i seguenti:
- "C: tmp.txt" fa riferimento a un file denominato "tmp.txt" nella directory corrente sull'unità C.
- "C: tempdir \ tmp.txt" fa riferimento a un file in una sottodirectory nella directory corrente sull'unità C.
[...]
Vecchia domanda, ma un'altra risposta applicabile. Se è necessario assicurarsi che il volume sia incluso in un percorso locale, è possibile utilizzare System.IO.Path.GetFullPath () in questo modo:
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
accede al file system e può generare una serie di possibili eccezioni. Vedi la mia risposta ( stackoverflow.com/a/35046453/704808 ) per un'alternativa che garantisce comunque un percorso completo.
Basandosi sulla risposta di weir : questo non genera percorsi non validi, ma restituisce anche false
percorsi come "C:", "C: dirname" e "\ 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
}
Notare che questo restituisce risultati diversi su Windows e Linux, ad esempio "/ path" è assoluto su Linux, ma non su Windows.
Test unitario:
[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);
}
}
Per verificare se un percorso è completo (MSDN) :
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
È un po 'più semplice di quanto è già stato proposto e restituisce ancora false per percorsi relativi all'unità come C:foo
. La sua logica si basa direttamente sulla definizione MSDN di "pienamente qualificato" e non ho trovato alcun esempio su cui si comporta male.
È interessante notare che .NET Core 2.1 sembra avere un nuovo metodo Path.IsPathFullyQualified
che utilizza un metodo interno PathInternal.IsPartiallyQualified
(posizione del collegamento accurata al 2017-04-17).
Per i posteri e un migliore autocontenimento di questo post, ecco l'implementazione di quest'ultimo come riferimento:
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]));
}
Questa è la soluzione che uso
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
Funziona nel modo seguente:
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
oC:\foo\.\.\.
Chiama la seguente funzione:
Path.IsPathFullyQualified(@"c:\foo")
Documento MSDN: Documento metodo Path.IsPathFullyQualified
Segue l'utile citazione dal documento MSDN:
Questo metodo gestisce i percorsi che utilizzano il separatore di directory alternativo. È un errore frequente presumere che i percorsi radicati ( IsPathRooted (String) ) non siano relativi. Ad esempio, "C: a" è relativo all'unità, ovvero viene risolto rispetto alla directory corrente per C: (radice, ma relativa). "C: \ a" è radicato e non relativo, ovvero la directory corrente non viene utilizzata per modificare il percorso.
Non sono proprio sicuro di cosa intendi per percorso completo (anche se dall'esempio intendi non relativo dalla radice in poi), beh, puoi usare la classe Path per aiutarti a lavorare con i percorsi fisici del filesystem, che dovrebbe coprire tu per la maggior parte delle eventualità.