我有这种方法从字符串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;
}
答案 0 :(得分:360)
您可以创建一个System.Uri对象,并使用IsFile验证它是一个文件,然后Uri.LocalPath来提取文件名。
这样更安全,因为它为您提供了检查URI有效性的方法。
编辑以回应评论:
要获得完整的文件名,我会使用:
Uri uri = new Uri(hreflink);
if (uri.IsFile) {
string filename = System.IO.Path.GetFileName(uri.LocalPath);
}
这会为您完成所有错误检查,并且与平台无关。所有特殊情况都可以快速,轻松地为您处理。
答案 1 :(得分:66)
Uri.IsFile不适用于http网址。它仅适用于“file://”。 来自MSDN:“当Scheme属性等于UriSchemeFile时,IsFile属性为 true 。” 所以你不能依赖它。
Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
答案 2 :(得分:35)
大多数答案要么不完整,要么不处理路径后面的内容(查询字符串/哈希)。
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/"); // ""
答案 3 :(得分:22)
对于http网址,接受的答案有问题。此外,Uri.LocalPath
执行Windows特定的转换,并且有人指出在那里留下查询字符串。更好的方法是使用Uri.AbsolutePath
为http网址执行此操作的正确方法是:
Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
答案 4 :(得分:17)
我认为这将满足您的需求:
var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
答案 5 :(得分:7)
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(hrefLink.Replace("/", "\\"));
}
当然,假设你已经解析了文件名。
编辑#2:
using System.IO;
private String GetFileName(String hrefLink)
{
return Path.GetFileName(Uri.UnescapeDataString(hrefLink).Replace("/", "\\"));
}
这应该处理文件名中的空格等。
答案 6 :(得分:2)
这是我可以使用的样本:
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");
答案 7 :(得分:0)
简单直接:
Uri uri = new Uri(documentAttachment.DocumentAttachment.PreSignedUrl);
fileName = Path.GetFileName(uri.LocalPath);
答案 8 :(得分:0)
public static string GetFileNameFromUrl (string url)
{
var decoded = HttpUtility.UrlDecode(url);
if (decoded.IndexOf("?") is {} queryIndex && queryIndex != -1)
{
decoded = decoded.Substring(0, queryIndex);
}
return Path.GetFileName(decoded);
}