如何从uri确定文件的文件扩展名

假设我有一个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 .owl /2001/08/baseball/baseball-ont我如何获得文件扩展名。 “

首先,我想确保您知道找不到URI链接的文件类型是不可能的,因为以.jpg结尾的链接可能允许您访问.exe文件(由于符号的原因,对于URL来说尤其如此)链接和.htaccess文件),因此,如果你想限制允许的文件类型,如果这是你当然想要的,那么从URI获取真正的扩展并不是一个坚如磐石的解决方案。 所以,我假设你只是想知道一个文件基于它的URI的扩展名,即使这不是完全值得信赖的;

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

 String uri = "http://sofzh.miximages.com/java/gsa"; String extension = uri.substring(uri.lastIndexOf(".")); 

上面的代码示例将从extension变量中的URI输出.png扩展extension ,注意a . (句点)包含在扩展中,如果要收集没有前缀句点的文件扩展名,请将子字符串索引增加1,如下所示:

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

在正则表达式(其他人经常使用的方法)上使用此方法的一个专业人员认为,这样可以节省大量资源,并且在执行相同结果时执行起来要轻得多。

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

 String uri = "http://sofzh.miximages.com/java/gsa"; if(uri.contains(".")) { String extension = uri.substring(url.lastIndexOf(".")); } 

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

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

我不会在这里讨论这两个function的解决方案,因为这不是首先要问的问题。

希望这可以帮助!

这有两个答案。

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

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

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

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

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

这个链接可能对那些仍然有问题的人有所帮助: 我如何获得具有Uri的文件的mime类型?

  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; } 

URLConnection.guessContentTypeFromName(url)将像第一个答案中一样传递mime类型。 也许你只是想要:

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

正则表达式消耗所有直到最后一个斜杠,然后到达一个句点并返回一个类似“.owl”或“”的扩展名。 (如果没有记错的话)

正如其他答案所解释的那样,如果不检查文件,您就不会真正了解内容类型。 但是,您可以从URL预测文件类型。

Java 几乎将此function作为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 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/."))); 

我是这样做的。

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

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