Відповіді:
Спробуйте використовувати System.IO.Path.IsPathRooted
? Він також повертається true
за абсолютні шляхи.
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
: уникнення доступу до файлової системи або викидання винятків для недійсного введення.
IsPathRooted
, він, звичайно, не був чимось значущим. GetFullPath
Лінія була включена , так що шлях оцінюється можна було спостерігати
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
Вищенаведена умова:
false
в більшості випадків, коли форматpath
недійсний (а не викидання виключення)true
лише якщо path
включає гучністьУ таких сценаріях, як той, який ставив ОП, тому він може бути більш підходящим, ніж умови попередніх відповідей. На відміну від вищевказаної умови:
path == System.IO.Path.GetFullPath(path)
кидає винятки, а не повертається false
в цих сценаріях:
System.IO.Path.IsPathRooted(path)
повертається, true
якщоpath
починається з одного роздільника каталогів.Нарешті, ось метод, який охоплює вищевказану умову, а також виключає інші можливі винятки:
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 зробив хороший коментар та альтернативну відповідь, вирішуючи цікавий випадок таких шляхів, як C:
і C:dir
. Щоб вирішити, як ви хочете обробляти такі шляхи, вам варто зайнятися глибоким зануренням до MSDN -> Програми для настільних ПК Windows -> Розробити -> Настільні технології -> Доступ до даних і зберігання -> Локальні файлові системи - -> Управління файлами -> Про управління файлами -> Створення, видалення та підтримка файлів -> Іменування файлів, шляхів та просторів імен -> Повністю кваліфіковані та відносні шляхи
Для функцій API Windows, що управляють файлами, імена файлів часто можуть бути відносно поточного каталогу, тоді як для деяких API потрібен повністю кваліфікований шлях. Ім'я файлу відносно поточного каталогу, якщо воно не починається з одного з наступних:
- Назва UNC будь-якого формату, яка завжди починається з двох зворотних косих символів ("\"). Для отримання додаткової інформації дивіться наступний розділ.
- Дисковий позначення зі зворотною косою рисою, наприклад "C: \" або "d: \".
- Один зворотний кут, наприклад, "\ каталог" або "\ file.txt". Це також називається абсолютним шляхом.
Якщо ім'я файлу починається лише з позначення диска, але не з косою рисою після двокрапки, це інтерпретується як відносний шлях до поточного каталогу на диску з вказаною літерою. Зауважте, що поточний каталог може бути або не бути кореневою каталогом залежно від того, для чого він був встановлений під час останньої операції "зміни каталогу" на цьому диску. Приклади такого формату:
- "C: tmp.txt" посилається на файл з назвою "tmp.txt" у поточному каталозі на накопичувачі C.
- "C: tempdir \ tmp.txt" посилається на файл у підкаталозі до поточного каталогу на диску CD.
[...]
Старе запитання, але ще одна відповідна відповідь. Якщо вам потрібно переконатися, що гучність включена в локальний шлях, ви можете використовувати System.IO.Path.GetFullPath () таким чином:
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
отримує доступ до файлової системи та може викинути ряд можливих винятків. Дивіться мою відповідь ( stackoverflow.com/a/35046453/704808 ) щодо альтернативи, яка все-таки забезпечує повний шлях.
Спираючись на відповідь weir : це не вказує на недійсні шляхи, але також повертається false
для таких шляхів, як "C:", "C: dirname" та "\ 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
}
Зауважте, що це повертає різні результати для Windows та Linux, наприклад, "/ path" є абсолютним для Linux, але не для Windows.
Тест одиниці:
[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);
}
}
Щоб перевірити, чи є шлях повністю кваліфікованим (MSDN) :
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
Це трохи простіше, ніж те, що вже було запропоновано, і воно все ще повертає помилку для шляхів, що відносяться до диска, як C:foo
. Його логіка базується безпосередньо на визначенні MSDN "повністю кваліфікованого", і я не знайшов жодних прикладів, з якими він неправильно поводиться.
Цікаво, однак, схоже, що .NET Core 2.1 має новий метод, Path.IsPathFullyQualified
який використовує внутрішній метод PathInternal.IsPartiallyQualified
(місце розташування посилань точно на 2018-04-17).
Для нащадків та кращого самозабезпечення цієї публікації, ось останній варіант здійснення для довідки:
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]));
}
Це рішення, яке я використовую
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
Це працює наступним чином:
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
абоC:\foo\.\.\.
Викличте таку функцію:
Path.IsPathFullyQualified(@"c:\foo")
MSDN doc: Path.IsPathFullyQualified метод
Корисний цитата з MSDN doc наступним чином:
Цей метод обробляє контури, які використовують альтернативний роздільник каталогів. Часта помилка вважає, що вкорінені шляхи ( IsPathRooted (String) ) не є відносними. Наприклад, "C: a" - відносний диск, тобто вирішено проти поточної каталогів для C: (вкорінене, але відносне). "C: \ a" вкорінюється і не є відносним, тобто поточний каталог не використовується для зміни шляху.
Я не дуже впевнений, що ви маєте на увазі під повним шляхом (хоча, маючи на увазі приклад, який ви маєте на увазі не відносне від кореня далі), ну, ви можете використовувати клас Path, щоб допомогти вам у роботі з шляхами фізичної файлової системи, які повинні охоплювати ви для більшості випадків.