Проверьте, является ли вход пути URL-адресом или локальным файлом
Я работаю в xmldataprovider, и у нас есть значение конфигурации "source", это значение может быть локальным файлом или URL-адресом
как
c:\data\test.xml --absolute data\test.xml - относительный
или url http:\mysite\test.xml
как я могу определить все эти случаи в коде
Я работаю С#
Ответы
Ответ 1
private static bool IsLocalPath(string p)
{
return new Uri(p).IsFile;
}
... или, если вы хотите включить поддержку определенных недопустимых URI...
private static bool IsLocalPath(string p)
{
if (p.StartsWith("http:\\"))
{
return false;
}
return new Uri(p).IsFile;
}
Пример использования
static void Main(string[] args)
{
CheckIfIsLocalPath("C:\\foo.txt");
CheckIfIsLocalPath("C:\\");
CheckIfIsLocalPath("http://www.txt.com");
}
private static void CheckIfIsLocalPath(string p)
{
var result = IsLocalPath(p); ;
Console.WriteLine("{0} {1} {2}", result, p, new Uri(p).AbsolutePath);
}
Ответ 2
Просто использование new Uri(yourPath)
не будет работать во всех случаях.
Сравнение различных сценариев (через LinqPad).
var tests = new[] {
Path.GetTempFileName(),
Path.GetDirectoryName(Path.GetTempFileName()),
"http://in.ter.net",
"http://in.ter.net/",
"http://in.ter.net/subfolder/",
"http://in.ter.net/subfolder/filenoext",
"http://in.ter.net/subfolder/file.ext",
"http://in.ter.net/subfolder/file.ext?somequerystring=yes",
Path.GetFileName(Path.GetTempFileName()),
Path.Combine("subfolder", Path.GetFileName(Path.GetTempFileName())),
};
tests.Select(test => {
Uri u;
try {
u = new Uri(test);
} catch(Exception ex) {
return new {
test,
IsAbsoluteUri = false,
// just assume
IsFile = true,
};
}
return new {
test,
u.IsAbsoluteUri,
u.IsFile,
};
}).Dump();
Результаты
![Результаты проверки пути Linqpad]()
Ответ 3
Просто установите правило для всего удаленного файла, он должен (и должен) включить протокол в URI:
http://
ftp://
и для локального файла это может быть
file://
для абсолютного пути и протокола для относительного.
Тогда простое регулярное выражение может помочь извлечь правильную информацию.
Ответ 4
В случае некорректного пути (несуществующий путь, пустая строка, пустая строка) Uri (p).IsFile выдает исключение.
На мой взгляд, лучше использовать два метода, чтобы различить, что есть:
private bool PathIsLocalFile(string path)
{
return File.Exists(path);
}
private bool PathIsUrl(string path)
{
if (File.Exists(path))
return false;
try
{
Uri uri = new Uri(path);
return true;
}
catch (Exception)
{
return false;
}
}
//
Microsoft docs:
public static bool Exists(string path);
Возвращает:
true, если вызывающий объект имеет необходимые разрешения, а путь содержит имя существующего файла; в противном случае - false. Этот метод также возвращает false, если путь равен null, недопустимый путь или строка нулевой длины. Если вызывающий объект не имеет достаточных разрешений для чтения указанного файла, исключение не генерируется, и метод возвращает false независимо от наличия пути.
//
Microsoft docs:
public Uri(string uriString);
Исключения:
T:System.ArgumentNullException:
uriString имеет значение null.
T:System.UriFormatException:
uriString пуст.-or- Схема, указанная в uriString, неверно сформирована. См. System.Uri.CheckSchemeName(System.String).- or- uriString содержит слишком много slashes.-or- Пароль, указанный в uriString, недействителен. -или- Имя хоста, указанное в uriString, недействительно. -или- имя файла, указанное в uriString, недопустимо. -или- Имя пользователя, указанное в uriString, недействительно. -или- Имя хоста или органа, указанное в uriString, не может быть завершено обратными слэшами. -или- Номер порта, указанный в uriString, недействителен или не может быть разобран. -или- Длина uriString превышает 65519 символов.-Or- Длина схемы, указанной в uriString, превышает 1023 символов. -или- В uriString имеется некорректная последовательность символов.-Or- Путь MS-DOS, указанный в uriString, должен начинаться с c:.\
Ответ 5
Это версия ответа @drzaus, избегающая подхода к обработке исключений. Существует Uri.TryCreate.
var tests = new[] {
Path.GetTempFileName(),
Path.GetDirectoryName(Path.GetTempFileName()),
"http://in.ter.net",
"http://in.ter.net/",
"http://in.ter.net/subfolder/",
"http://in.ter.net/subfolder/filenoext",
"http://in.ter.net/subfolder/file.ext",
"http://in.ter.net/subfolder/file.ext?somequerystring=yes",
Path.GetFileName(Path.GetTempFileName()),
Path.Combine("subfolder", Path.GetFileName(Path.GetTempFileName()))};
tests.Select(test =>
{
if (Uri.TryCreate(test, UriKind.Absolute, out var u))
{
return new { test, u.IsAbsoluteUri, u.IsFile };
}
return new { test, IsAbsoluteUri = false, IsFile = true };
}
).Dump();
И как методы расширения:
public static bool IsLocalAbsolutePath(this string input)
{
if (Uri.TryCreate(input, UriKind.Absolute, out var uri))
{
return uri.IsFile;
}
return false;
}
public static bool IsRemoteAbsolutePath(this string input)
{
if (Uri.TryCreate(input, UriKind.Absolute, out var uri))
{
return !uri.IsFile;
}
return false;
}