【问题标题】:Get file extension or "HasExtension" type bool from Uri object C#从 Uri 对象 C# 获取文件扩展名或“HasExtension”类型 bool
【发布时间】:2012-10-14 09:26:05
【问题描述】:

快速提问:

谁能想到比 RegEx 或一般文本搜索更好的方法来确定 Uri 对象(不是 URL 字符串)是否具有文件扩展名?

欢迎任何想法。如果我在 .NET 框架/Uri 类中遗漏了已经执行此操作的某些内容,请道歉。


稍微复杂一点。


我已接受 craigtp 的回答;但是,对于我需要的解决方案就是这样。

var hasExtension = Path.HasExtension(requestUri.AbsolutePath);

致所有对此有所尝试的人。要获得完整而全面的答案,您显然需要一个 mime 类型字典来进行进一步检查。例如 http://example/this.is.sort.of.valid.but.not.a.mime.type 会返回 "true" has Path.HasExtension,但是,对于我需要的,我永远不会有这种类型的路径进入。

【问题讨论】:

  • 我不确定你是否能够区分最后两种情况,除非你有一个“公认的”扩展名列表。
  • 我已经在我的编辑中解决了这个问题——不过很好。
  • “我已经接受了 craigtp 的答案;但是,”嘿@LiverpoolsNumber9,这应该通过在下面的新答案中给出您自己的答案来更改,然后将其标记为答案(这是,由方式,完全可以接受,即使您立即有自己的答案)。您仍然可以将功劳归功于其他有帮助的答案,但正如您所展示的那样,标记的答案并不是该问题的完整答案,即如何从 Uri 类型中获得此答案。

标签: c# .net uri


【解决方案1】:

您可以使用System.IO.Path 类的HasExtension 方法来确定Uri 的字符串是否具有扩展名。

通过使用Uri 对象的AbsoluteUri 属性,您可以检索代表Uri 的完整字符串。将此字符串传递给 Path 类的 HasExtension 方法将正确返回一个布尔值,指示 Uri 是否包含文件扩展名。

将以下代码复制并粘贴到一个简单的控制台应用程序中进行测试。只有myUri3myUrl4返回True,这也说明HasExtension方法可以正确处理文件名(和扩展名)后面的附加字符(即Querystrings)。

using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri myURI1 = new Uri(@"http://www.somesite.com/");
            Uri myURI2 = new Uri(@"http://www.somesite.com/filenoext");
            Uri myURI3 = new Uri(@"http://www.somesite.com/filewithext.jpg");
            Uri myURI4 = new Uri(@"http://www.somesite.com/filewithext.jpg?q=randomquerystring");

            Console.WriteLine("Does myURI1 have an extension: " + Path.HasExtension(myURI1.AbsoluteUri));
            Console.WriteLine("Does myURI2 have an extension: " + Path.HasExtension(myURI2.AbsoluteUri));
            Console.WriteLine("Does myURI3 have an extension: " + Path.HasExtension(myURI3.AbsoluteUri));
            Console.WriteLine("Does myURI4 have an extension: " + Path.HasExtension(myURI4.AbsoluteUri));

            Console.ReadLine();
        }
    }
}

编辑:

根据提问者关于确定扩展是否是有效扩展的编辑,我在下面编写了一些新代码(复制并粘贴到控制台应用程序中):

using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri myUri1 = new Uri("http://www.somesite.com/folder/file.jpg?q=randomquery.string");
            string path1 = String.Format("{0}{1}{2}{3}", myUri1.Scheme, Uri.SchemeDelimiter, myUri1.Authority, myUri1.AbsolutePath);
            string extension1 = Path.GetExtension(path1);
            Console.WriteLine("Extension of myUri1: " + extension1);

            Uri myUri2 = new Uri("http://www.somesite.com/folder/?q=randomquerystring");
            string path2 = String.Format("{0}{1}{2}{3}", myUri2.Scheme, Uri.SchemeDelimiter, myUri2.Authority, myUri2.AbsolutePath);
            string extension2 = Path.GetExtension(path2);
            Console.WriteLine("Extension of myUri1: " + extension2);

            Console.ReadLine();
        }
    }
}

这个新代码现在解构 Uri 对象的所有组成部分(即 Scheme - http 部分等),特别是 删除 Uri 的任何查询字符串部分。这解决了Adriano 在对此答案的评论中指出的潜在问题,即查询字符串可能包含点字符(从而可能会弄乱HasExtension 方法)。

一旦 Uri 被解构,我们现在可以正确地确定 Uri 字符串是否一个扩展以及那个扩展是什么

从这里开始,这只是将此扩展名与已知有效扩展名列表进行匹配的情况。这部分是 .NET 框架永远不会提供给您的,因为 任何 文件扩展名可能是有效的(如果需要,任何应用程序都可以组成自己的文件扩展名!)

【讨论】:

  • -1 AbsoluteUri 不会从 URI 中删除查询和片段。
  • @Adriano - 在 OP 的原始问题中(仅询问 Uri 是否有扩展名,而不是 what 它是),它没有必须!
  • 嗯,一个URI可以有查询和片段部分(并且点可以在查询部分,而不是在最后一段)
  • @Adriano 即使他们这样做了,他们仍然有一个扩展名。你能举一个他的方法失败的例子吗?
  • 我明白了,也许他应该使用Uri.AbsolutePath 而不是Uri.AbsoluteUri
【解决方案2】:

别人建议的Uri.IsFile属性不起作用。

来自文档

The IsFile property is true when the Scheme property equals UriSchemeFile.

file://server/filename.ext"

http://msdn.microsoft.com/en-us/library/system.uri.isfile.aspx

您可以做的是获取 URI 的 AbsolutePath(例如对应于 /contact 或 /images/logo.png),然后使用 FileInfo 类检查/获取扩展名。

var uris = new List<Uri>()
{
  new Uri("http://mysite.com/contact"),
  new Uri("http://mysite.com/images/logo.png"),
  new Uri("http://mysite.com/images/logo.png?query=value"),
};

foreach (var u in uris)
{
  var fi = new FileInfo(u.AbsolutePath);
  var ext = fi.Extension;
  if (!string.IsNullOrWhiteSpace(ext))
  {
    Console.WriteLine(ext);
  }
}

您可能需要检查支持的扩展列表以处理更复杂的情况(contact.is.sortof.valid 和 contact.is.sortof.valid.png)

测试:

"http://mysite.com/contact"                             //no ext
"http://mysite.com/contact?query=value"                 //no ext
"http://mysite.com/contact?query=value.value"           //no ext
"http://mysite.com/contact/"                            //no ext
"http://mysite.com/images/logo.png"                     //.png
"http://mysite.com/images/logo.png?query=value"         //.png
"http://mysite.com/images/logo.png?query=value.value"   //.png
"http://mysite.com/contact.is.sortof.valid"             //.valid
"http://mysite:123/contact.is.sortof.valid"              //.valid

【讨论】:

  • 也许 OP 可以将您的答案与这个 (stackoverflow.com/questions/3937958/…) 结合起来,根据 MIME 类型配置生成支持的扩展列表。
  • 嗨 - 感谢@wdavo - 它有效,但我使用了“Path.HasExtension”,它有效地做同样的事情。
  • 你也可以使用Path.GetExtension(request.Url.AbsolutePath)代替FileInfo
【解决方案3】:

看看 UriBuilder 类。您不仅可以检索 url 的某些部分,还可以随意交换它们。

public bool HasExtension(Uri myUri)
{
    var validExtensions = new List<string>() { ".png", ".jpg" };
    var builder = UriBuilder(myUri)
    foreach (var extension in validExtensions) {
        if(builder.Path.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
            return true;
    return false;
}

【讨论】:

    【解决方案4】:

    这是我的解决方案;)

            var inputString = ("http://ask.com/pic.JPG http://aSk.com/pIc.JPG "
            + "http://ask.com/pic.jpg "
            + "http://yoursite.com/contact "
            + "http://yoursite.com/contact?query=value "
            + "http://yoursite.com/contact?query=value.value "
            + "http://yoursite.com/contact/ "
            + "http://yoursite.com/images/Logo.pnG "
            + "http://yoursite.com/images/lOgo.pNg?query=value "
            + "http://yoursite.com/images/logo.png?query=value.value "
            + "http://yoursite.com/contact.is.sortof.valid "
            + "http://mysite:123/contact.is.sortof.valid").Split(' ');
    
            var restultString = "";
    
            foreach (var is1 in inputString)
            {
                restultString += (!string.IsNullOrEmpty(restultString) ? " " : "") +
                      (Path.HasExtension(is1) ? Path.ChangeExtension(is1, Path.GetExtension(is1).ToLower()) : is1);
            }
    

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 2014-05-30
      • 1970-01-01
      • 2019-02-06
      • 2013-05-28
      • 2011-06-04
      • 1970-01-01
      相关资源
      最近更新 更多