Проверьте, указан ли полный путь
есть ли способ проверить, является ли данный путь полным путем? Прямо сейчас я делаю это:
if (template.Contains(":")) //full path already given
{
}
else //calculate the path from local assembly
{
}
но должен быть более элегантный способ проверить это?
8 ответов:
попробуйте использовать
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]\foo"
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 desktop applications -->разработки -->технологии для настольных ПК -->доступ к данным и их хранение -->Локальные Файловые Системы -->Управления -->Об Управлении -->создание, удаление и сохранение файлов -->именование файлов, путей и пространств имен -->полное и относительное Путидля функций Windows API, которые управляют файлами, имена файлов часто могут быть относительно текущего каталога, в то время как некоторые API требуют полностью квалифицированный путь. Имя файла относится к текущему каталогу, если оно не начинается с одного из следующих:
- UNC-имя любого формата, которое всегда начинается с двух символов обратной косой черты ("\"). Дополнительные сведения см. В следующем разделе.
- диск обозначение С обратной косой чертой, например "C:\" или "d:\".
- одна обратная косая черта, например, "\directory" или "\file.формат txt." Это также называется абсолютным путем.
если имя файла начинается с обозначения диска, но не обратная косая черта после двоеточия интерпретируется как относительный путь к текущий каталог на диске с указанной буквы. Заметить что текущий каталог может быть или не быть корневым каталогом в зависимости на что было установлено во время последней "смены каталога" операция на этом диске. Примеры этого формата следующие:
- " C: tmp.txt " относится к файлу с именем "tmp.txt" в текущем каталоге на диске C.
- "C:tempdir\tmp.txt " относится к файлу в подкаталоге к текущему каталогу на диске C.
[...]
попробовать
System.IO.Path.IsPathRooted(template)
работает для UNC-путей, а также локальных.
например.
Path.IsPathRooted(@"\MyServer\MyShare\MyDirectory") // returns true Path.IsPathRooted(@"C:\MyDirectory") // returns true
старый вопрос, но еще один применимый ответ. Если вам нужно убедиться, что Том включен в локальный путь, вы можете использовать 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 }
дом на плотинаответ: это не бросает для недопустимых путей, но и возвращает
false
на пути как "C:", в "каталог" и "путь\".public static bool IsFullPath(string path) { if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path)) return false; var 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; return !(pathRoot == path && pathRoot.StartsWith("\\") && pathRoot.IndexOf('\', 2) == -1); // A UNC server name without a share name (e.g "\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); } 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(@"\"); }
Это немного проще, чем то, что уже было предложено, и он по-прежнему возвращает false для езды-относительные пути типа
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