225

我有这种从字符串 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;
}
4

9 回答 9

418

您可以只创建一个 System.Uri 对象,并使用 IsFile 来验证它是一个文件,然后使用 Uri.LocalPath来提取文件名。

这更安全,因为它还为您提供了检查 URI 有效性的方法。


编辑以回应评论:

要获得完整的文件名,我会使用:

Uri uri = new Uri(hreflink);
if (uri.IsFile) {
    string filename = System.IO.Path.GetFileName(uri.LocalPath);
}

这会为您完成所有错误检查,并且与平台无关。所有特殊情况都可以快速轻松地为您处理。

于 2009-07-09T18:11:17.430 回答
85

Uri.IsFile 不适用于 http 网址。它仅适用于“file://”。来自MSDN:“当 Scheme 属性等于 UriSchemeFile 时, IsFile 属性为真。” 所以你不能依赖它。

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
于 2014-02-19T10:28:32.073 回答
70

大多数其他答案要么不完整,要么不处理路径之后的内容(查询字符串/哈希)。

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"
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/");              // ""
于 2016-11-01T13:37:49.290 回答
32

对于 http url,接受的答案是有问题的。此外,还有Uri.LocalPathWindows 特定的转换,正如有人指出的那样,在那里留下了查询字符串。更好的方法是使用Uri.AbsolutePath

对 http url 执行此操作的正确方法是:

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
于 2015-09-15T19:26:12.293 回答
25

我认为这将满足您的需求:

var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
于 2017-02-03T19:56:09.280 回答
8
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("/", "\\"));
}

这应该处理文件名中的空格等。

于 2009-07-09T18:11:25.933 回答
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");
于 2018-01-28T15:52:38.173 回答
1

简单直接:

            Uri uri = new Uri(documentAttachment.DocumentAttachment.PreSignedUrl);
            fileName = Path.GetFileName(uri.LocalPath);
于 2019-10-17T11:36:25.913 回答
0

截至 2020 年,处理查询字符串和编码 URL

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);
}
于 2020-11-17T23:08:40.773 回答