Odpowiedzi:
Spróbuj użyć System.IO.Path.IsPathRooted
? Wraca również true
dla ścieżek bezwzględnych.
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
: unikania dostępu do systemu plików lub zgłaszania wyjątków w przypadku nieprawidłowych danych wejściowych.
IsPathRooted
pewnością nie była to nic znaczącego. GetFullPath
Linia została włączona tak, że ścieżka jest oceniany można zaobserwować
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
Powyższy warunek:
false
w większości przypadków, gdy format path
jest nieprawidłowy (zamiast zgłaszać wyjątek)true
tylko wtedy, gdy path
zawiera objętośćW scenariuszach takich jak ten, który przedstawił PO, może zatem być bardziej odpowiedni niż warunki z wcześniejszych odpowiedzi. W przeciwieństwie do powyższego warunku:
path == System.IO.Path.GetFullPath(path)
zgłasza wyjątki zamiast zwracać false
w następujących scenariuszach:
System.IO.Path.IsPathRooted(path)
zwraca, true
jeśli path
zaczyna się od pojedynczego separatora katalogu.Wreszcie, oto metoda, która obejmuje powyższy warunek, a także wyklucza pozostałe możliwe wyjątki:
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);
}
EDYCJA: EM0 zrobił dobry komentarz i alternatywną odpowiedź, odnosząc się do ciekawego przypadku ścieżek takich jak C:
i C:dir
. Aby pomóc zdecydować, w jaki sposób chcesz obsłużyć takie ścieżki, możesz zagłębić się w MSDN -> Aplikacje klasyczne Windows -> Programowanie -> Technologie komputerowe -> Dostęp do danych i przechowywanie -> Lokalne systemy plików - -> Zarządzanie plikami -> Informacje o zarządzaniu plikami -> Tworzenie, usuwanie i konserwacja plików -> Nazywanie plików, ścieżek i przestrzeni nazw -> W pełni kwalifikowane a względne ścieżki
W przypadku funkcji interfejsu API systemu Windows, które manipulują plikami, nazwy plików mogą często odnosić się do bieżącego katalogu, podczas gdy niektóre interfejsy API wymagają w pełni kwalifikowanej ścieżki. Nazwa pliku jest określana względem bieżącego katalogu, jeśli nie zaczyna się od jednego z następujących elementów:
- Nazwa UNC dowolnego formatu, która zawsze zaczyna się od dwóch znaków ukośnika odwrotnego („\”). Więcej informacji można znaleźć w następnej sekcji.
- Oznaczenie dysku z ukośnikiem odwrotnym, na przykład „C: \” lub „d: \”.
- Pojedynczy ukośnik odwrotny, na przykład „\ katalog” lub „\ plik.txt”. Nazywa się to również ścieżką absolutną.
Jeśli nazwa pliku zaczyna się od samego oznaczenia dysku, ale nie od ukośnika odwrotnego po dwukropku, jest interpretowana jako ścieżka względna do bieżącego katalogu na dysku z określoną literą. Zwróć uwagę, że katalog bieżący może być katalogiem głównym lub nie, w zależności od tego, na co został ustawiony podczas ostatniej operacji „zmiany katalogu” na tym dysku. Przykłady tego formatu są następujące:
- „C: tmp.txt” odnosi się do pliku o nazwie „tmp.txt” w bieżącym katalogu na dysku C.
- „C: tempdir \ tmp.txt” odnosi się do pliku w podkatalogu do bieżącego katalogu na dysku C.
[…]
Stare pytanie, ale jeszcze jedna odpowiednia odpowiedź. Jeśli chcesz upewnić się, że wolumin jest uwzględniony w ścieżce lokalnej, możesz użyć System.IO.Path.GetFullPath () w następujący sposób:
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
uzyskuje dostęp do systemu plików i może zgłosić kilka możliwych wyjątków. Zobacz moją odpowiedź ( stackoverflow.com/a/35046453/704808 ), aby znaleźć alternatywę, która nadal zapewnia pełną ścieżkę.
Opierając się na odpowiedzi jazu : nie powoduje to zgłaszania nieprawidłowych ścieżek, ale zwraca również false
ścieżki, takie jak „C:”, „C: dirname” i „\ 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
}
Zwróć uwagę, że zwraca to różne wyniki w systemach Windows i Linux, np. „/ Path” jest bezwzględne w systemie Linux, ale nie w systemie Windows.
Test jednostkowy:
[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);
}
}
Aby sprawdzić, czy ścieżka jest w pełni kwalifikowana (MSDN) :
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
Jest to nieco prostsze niż to, co zostało już zaproponowane, i nadal zwraca wartość false dla ścieżek względem dysku, takich jak C:foo
. Jego logika jest oparta bezpośrednio na definicji „w pełni kwalifikowanej” w MSDN i nie znalazłem żadnych przykładów, na których źle się zachowuje.
Co ciekawe, wydaje się, że .NET Core 2.1 ma nową metodę, Path.IsPathFullyQualified
która wykorzystuje metodę wewnętrzną PathInternal.IsPartiallyQualified
(lokalizacja linków jest dokładna na 17.04.2018).
Dla potomności i lepszego samowystarczalności tego posta, oto implementacja tego ostatniego w celach informacyjnych:
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]));
}
To jest rozwiązanie, którego używam
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
Działa to w następujący sposób:
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
lubC:\foo\.\.\.
Wywołaj następującą funkcję:
Path.IsPathFullyQualified(@"c:\foo")
Dokument MSDN: Metoda Path.IsPathFullyQualified
Oto przydatny cytat z dokumentu MSDN:
Ta metoda obsługuje ścieżki, które używają alternatywnego separatora katalogu. Częstym błędem jest zakładanie, że zakorzenione ścieżki ( IsPathRooted (String) ) nie są względne. Na przykład „C: a” jest względnym dyskiem, to znaczy jest rozpoznawany względem bieżącego katalogu dla C: (zakorzeniony, ale względny). „C: \ a” jest zakorzenione i nie jest względne, to znaczy bieżący katalog nie jest używany do modyfikowania ścieżki.
Nie jestem do końca pewien, co masz na myśli przez pełną ścieżkę (chociaż zakładając z przykładu, że masz na myśli nie względną od korzenia), możesz użyć klasy Path, aby pomóc ci w pracy ze ścieżkami fizycznego systemu plików, które powinny obejmować w większości przypadków.