【问题标题】:How to determine the file extension of a file from a uri如何从uri确定文件的文件扩展名
【发布时间】:2011-03-15 03:04:27
【问题描述】:

假设我有一个 URI,我想找到返回的文件的文件扩展名,我在 Java 中需要做什么。

例如http://www.daml.org/2001/08/baseball/baseball-ont 的文件是http://www.daml.org/2001/08/baseball/baseball-ont.owl

当我这样做时

    URI uri = new URI(address); 
    URL url = uri.toURL();
    String file = url.getFile();
    System.out.println(file);

我无法看到带有.owl 扩展名的完整文件名,只能看到/2001/08/baseball/baseball-ont 我如何获得文件扩展名。 ``

【问题讨论】:

    标签: java url file uri


    【解决方案1】:

    对此有两个答案。

    如果 URI 没有“文件扩展名”,则无法通过查看文本或将其转换为 File 来推断。通常,URI 或文件都不需要扩展名。扩展名只是一个文件命名约定

    您真正追求的是文件的媒体类型/MIMEtype/内容类型。您可以通过执行以下操作来确定媒体类型:

    URLConnection conn = url.connect();
    String type = conn.getContentType();
    

    但是,如果服务器没有在响应中设置内容类型,getContentType() 方法将返回 null。 (或者它可能会给你错误的内容类型或非特定的内容类型。)那时,你需要诉诸于内容类型“猜测”,我不知道这是否会给你一个足够具体的内容在这种情况下输入。

    但如果你“知道”文件应该是 OWL,那你为什么不给它一个“.owl”扩展名呢?

    【讨论】:

    • 在没有网络的情况下会失败
    • 好吧。但是,如果没有互联网,您将无法获取文件。所以它的类型是什么并不重要。 (如果你真的需要“知道”现在,你可以等到互联网恢复,或者“根据扩展名猜测”。)
    • 也许您只需要知道扩展名而不获取文件?
    • 如果扩展名不在 URI 中,并且您无法获取文件或其元数据以找出文件类型的真正含义,那么就没有解决方案......涉及时间旅行、千里眼或其他一些莫名其妙的东西。
    【解决方案2】:

    URLConnection.guessContentTypeFromName(url) 将提供第一个答案中的 mime 类型。 也许你只是想要:

    String extension = url.getPath().replaceFirst("^.*/[^/]*(\\.[^\\./]*|)$", "$1");
    

    正则表达式从最后一个斜杠到句号,然后返回一个扩展名,如“.owl”或“”。 (如果没记错的话)

    【讨论】:

    • URLConnection.guessContentTypeFromName(address) //(字符串地址)是最好的答案,恕我直言。
    【解决方案3】:

    首先,我想确保您知道不可能找出 URI 链接的文件类型,因为以 .jpg 结尾的链接可能会让您访问 .exe 文件(对于URL,由于符号链接和 .htaccess 文件),因此如果您想限制允许的文件类型,那么从 URI 获取 real 扩展名并不是一个可靠的解决方案,如果这是您'当然要去。所以,我假设您只是想知道基于文件 URI 的文件具有什么扩展名,即使这并不完全值得信赖;

    您可以使用以下方法从任何 URI、URL 或文件路径获取扩展名。您不必使用任何库或扩展,因为这是基本的 Java 功能。该解决方案获取URI字符串中最后一个.(句点)符号的位置,并创建一个子字符串,从句点符号的位置开始,到URI字符串的末尾结束。

    String uri = "http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/integrating_apps/images/google_logo.png";
    String extension = uri.substring(uri.lastIndexOf("."));
    

    上面的代码示例将从 extension 变量中的 URI 输出 .png 扩展名,请注意扩展名中包含 .(句点),如果您想收集不带前缀句点,子串索引加一,像这样:

    String extension = uri.substring(url.lastIndexOf(".") + 1);
    

    在正则表达式(其他人经常使用的一种方法)上使用这种方法的一个优点是,在给出相同结果的同时,这种方法消耗的资源少得多,执行起来也少得多。

    此外,您可能希望确保 URL 包含句点字符,使用以下代码来实现:

    String uri = "http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/integrating_apps/images/google_logo.png";
    if(uri.contains(".")) {
        String extension = uri.substring(url.lastIndexOf("."));
    }
    

    您可能希望进一步改进功能以创建更强大的系统。两个例子可能是:

    • 通过检查 URI 是否存在或通过确保 URI 的语法有效(可能使用正则表达式)来验证 URI。
    • 修剪扩展以删除不需要的空格。

    我不会在这里介绍这两个功能的解决方案,因为这不是一开始就被问到的。

    希望这会有所帮助!

    【讨论】:

    • 如果 url 在文件名或哈希后有问号,这将不起作用。
    • 您添加的句点字符检查没有任何用处,因为无论如何在顶级域之前都有一个句点。
    • 如果 uri 不包含句点字符,我可以假设 uri 不是文件的 uri 吗?
    • @AndroidDeveloper,没有。以下面的 url 为例。 fluttercommunity.dev/_github/header/flutter_webview_plugin
    • Uri 与 Url 不同
    【解决方案4】:

    此链接可能对仍有问题的人有所帮助: How I can get the mime type of a file having its Uri?

     public static String getMimeType(Context context, Uri uri) {
        String extension;
    
        //Check uri format to avoid null
        if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
            //If scheme is a content
            final MimeTypeMap mime = MimeTypeMap.getSingleton();
            extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));
        } else {
            //If scheme is a File
            //This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
            extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
    
        }
    
        return extension;
    }
    

    【讨论】:

      【解决方案5】:

      我就是这样做的。

      您可以通过更多验证检查任何文件扩展名:

      String stringUri = uri.toString();
      String fileFormat = "png";
      
                          if (stringUri.contains(".") && fileFormat.equalsIgnoreCase(stringUri.substring(stringUri.lastIndexOf(".") + 1))) {
      
                              // do anything
      
                          } else {
      
                              // invalid file
      
                          }
      

      【讨论】:

        【解决方案6】:

        正如其他答案所解释的,如果不检查文件,您实际上并不知道内容类型。但是,您可以从 URL 预测文件类型。

        Java几乎将这个功能作为URL 类的一部分提供。 URL::getFile方法会智能抓取URL的文件部分:

        final URL url = new URL("http://www.example.com/a/b/c/stuff.zip?u=1");
        final String file = url.getFile(); // file = "/a/b/c/stuff.zip?u=1"
        

        我们可以用它来编写我们的实现:

        public static Optional<String> getFileExtension(final URL url) {
        
            Objects.requireNonNull(url, "url is null");
        
            final String file = url.getFile();
        
            if (file.contains(".")) {
        
                final String sub = file.substring(file.lastIndexOf('.') + 1);
        
                if (sub.length() == 0) {
                    return Optional.empty();
                }
        
                if (sub.contains("?")) {
                    return Optional.of(sub.substring(0, sub.indexOf('?')));
                }
        
                return Optional.of(sub);
            }
        
            return Optional.empty();
        }
        

        这个实现应该正确处理边缘情况:

        assertEquals(
            Optional.of("zip"), 
            getFileExtension(new URL("http://www.example.com/stuff.zip")));
        
        assertEquals(
            Optional.of("zip"), 
            getFileExtension(new URL("http://www.example.com/stuff.zip")));
        
        assertEquals(
            Optional.of("zip"), 
            getFileExtension(new URL("http://www.example.com/a/b/c/stuff.zip")));
        
        assertEquals(
            Optional.empty(), 
            getFileExtension(new URL("http://www.example.com")));
        
        assertEquals(
            Optional.empty(), 
            getFileExtension(new URL("http://www.example.com/")));
        
        assertEquals(
            Optional.empty(), 
            getFileExtension(new URL("http://www.example.com/.")));
        

        【讨论】:

          【解决方案7】:

          接受的答案对于包含“?”的 url 没有用或扩展后的“/”。所以,要删除多余的字符串, 您可以使用 getLastPathSegment() 方法。它只为您提供来自 uri 的名称,然后您可以获得如下扩展名:

          String name = uri.getLastPathSegment();
          //Here uri is your uri from which you want to get extension
          String extension = name.substring(name.lastIndexOf("."));
          

          如果你想删除点,上面的代码得到扩展名。(点)然后你可以编码如下:

          String extension = name.substring(name.lastIndexOf(".") + 1);
          

          【讨论】:

          • 嘿 Tedinoz,您没有注意到 tim visee 回答的评论吗?如果 url 有 '?' 这将不起作用或文件名后的“/”。如果您有来自 firebase 的图像 url,那么它会在“。”之后给出整个字符串。 (点)。例如,如果 url 是“firebasestorage.googleapis.com/v0/b/mememaker-13a8c.appspot.com/…”,那么它给出的扩展名是“.jpg?alt=media&token=e89f415c-8338-4e56-9d4c-9a87b6e0edb5”,但我只想要“.jpg”作为扩展名
          【解决方案8】:

          另一种在接受的答案中没有提到的有用方法是,如果你有一个远程 url,那么你可以从 URLConnection 获取 mimeType,比如

            URLConnection urlConnection = new URL("http://www.google.com").openConnection();
            String mimeType = urlConnection.getContentType(); 
          

          现在要从 MimeType 获取文件扩展名,我会参考这个post

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-13
            • 1970-01-01
            • 2012-02-04
            • 2015-01-01
            • 1970-01-01
            • 2019-05-22
            相关资源
            最近更新 更多