Получить имя файла из URI string в C#
У меня есть этот метод для захвата имени файла из строки URI. Что я могу сделать, чтобы сделать его более надежным?
private string GetFileName(string hrefLink)
{
string[] parts = hrefLink.Split('/');
string fileName = "";
if (parts.Length > 0)
fileName = parts[parts.Length - 1];
else
fileName = hrefLink;
return fileName;
}
7 ответов
вы можете просто создать систему.Объект Uri и используйте IsFile, чтобы проверить, что это файл, затем Uri.LocalPath для извлечения имени файла.
Это намного безопаснее, так как это дает вам возможность проверить действительность URI.
редактировать в ответ на комментарий:
чтобы получить только полное имя файла, я бы использовал:
Uri uri = new Uri(hreflink);
if (uri.IsFile) {
string filename = System.IO.Path.GetFileName(uri.LocalPath);
}
это делает всю проверку ошибок для вас и является платформо-нейтральных. Все специальные случаи получить выполняется быстро и легко.
Uri.IsFile не работает с URL-адресами http. Он работает только для " file://". От MSDN: "свойство IsFile является правда когда свойство Scheme равно UriSchemeFile." Так что ты не можешь на это рассчитывать.
Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
большинство ответов либо неполные, либо не имеют дело с вещами, идущими после пути (строка запроса/хэш).
readonly static Uri SomeBaseUri = new Uri("http://canbeanything");
static string GetFileNameFromUrl(string url)
{
Uri uri;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
uri = new Uri(SomeBaseUri, url);
return Path.GetFileName(uri.LocalPath);
}
результаты теста:
GetFileNameFromUrl(""); // ""
GetFileNameFromUrl("test"); // "test.xml"
GetFileNameFromUrl("test.xml"); // "test.xml"
GetFileNameFromUrl("/test.xml"); // "test.xml"
GetFileNameFromUrl("/test.xml?q=1"); // "test.xml"
GetFileNameFromUrl("/test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3#aidjsf"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/a/b/c/d"); // "d"
GetFileNameFromUrl("http://www.a.com/a/b/c/d/e/"); // ""
принятый ответ проблематичен для HTTP-адресов. Более того!--4-->Uri.LocalPath
делает конкретные преобразования Windows, и, как кто-то указал, оставляет строки запроса там. Лучший способ-использовать Uri.AbsolutePath
правильный способ сделать это для HTTP urls:
Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
Я думаю, что это сделает то, что вам нужно:
var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(hrefLink.Replace("/", "\"));
}
это предполагает, конечно, что вы проанализировали имя файла.
EDIT #2:
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(Uri.UnescapeDataString(hrefLink).Replace("/", "\"));
}
Это должно обрабатывать пробелы и тому подобное в имени файла.
Это мой образец вы можете использовать:
public static string GetFileNameValidChar(string fileName)
{
foreach (var item in System.IO.Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(item.ToString(), "");
}
return fileName;
}
public static string GetFileNameFromUrl(string url)
{
string fileName = "";
if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
{
fileName = GetFileNameValidChar(Path.GetFileName(uri.AbsolutePath));
}
string ext = "";
if (!string.IsNullOrEmpty(fileName))
{
ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
ext = ".html";
else
ext = "";
return GetFileNameValidChar(fileName + ext);
}
fileName = Path.GetFileName(url);
if (string.IsNullOrEmpty(fileName))
{
fileName = "noName";
}
ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
ext = ".html";
else
ext = "";
fileName = fileName + ext;
if (!fileName.StartsWith("?"))
fileName = fileName.Split('?').FirstOrDefault();
fileName = fileName.Split('&').LastOrDefault().Split('=').LastOrDefault();
return GetFileNameValidChar(fileName);
}
использование:
var fileName = GetFileNameFromUrl("http://cdn.p30download.com/?b=p30dl-software&f=Mozilla.Firefox.v58.0.x86_p30download.com.zip");