2009-07-09 32 views
160

我有这种方法从字符串URI中获取文件名。我可以做些什么来使其更健壮?从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; 
} 

回答

321

你可以只作出的System.Uri对象,并使用ISFILE来验证它的一个文件,然后Uri.LocalPath提取文件名。

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


编辑评论:

得到公正的完整文件名,我会使用:

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

但这所有的错误检查你的,并且是与平台中性。所有特殊情况都可以快速轻松地为您处理。

+0

我同意,你应该真的使用Uri类,因为它已经为你做这个东西。 +1 – 2009-07-09 18:17:52

+0

是的,就像它看起来像你自己的Uri类一样简单,它为你提供了大量的预先解析/验证/编码的好东西。 – STW 2009-07-09 18:23:14

+2

没错,但我只需要文件名,而不是完整的文件路径。我是不是仍然要在Uri.LocalPath上做这一步? – paulwhit 2009-07-10 17:46:52

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("/", "\\")); 
} 

这应该处理空间和文件名等。

51

Uri.IsFile不能与http url一起使用。它只适用于“file://”。 从MSDN:“IsFile属性为true当Scheme属性等于UriSchemeFile时。” 所以你不能依赖那个。

Uri uri = new Uri(hreflink); 
string filename = System.IO.Path.GetFileName(uri.LocalPath); 
19

对于http url,接受的答案是有问题的。此外Uri.LocalPath会进行Windows特定的转换,并且有人指出在那里留下查询字符串。更好的方法是使用Uri.AbsolutePath

的正确方法http网址做到这一点的是:

Uri uri = new Uri(hreflink); 
string filename = System.IO.Path.GetFileName(uri.AbsolutePath); 
23

大多数的答案是不完整或不与路径之后的东西来(查询字符串/散列处理)。

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/");    // "" 
8

我认为这会做你的需要:

var uri = new Uri(hreflink); 
var filename = uri.Segments.Last(); 
0

这是我的示例中,您可以使用:

 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"); 
相关问题