如何在Java中从MIME类型确定适当的文件扩展名

40
我正在将文件上传到Amazon S3存储桶,并可以访问InputStream和包含文件MIME类型的字符串,但无法访问原始文件名。在将文件推送到S3之前,需要我实际创建文件名和扩展名。是否有库或方便的方法可以从MIME类型确定要使用的适当扩展名?
我看到了一些关于Apache Tika库的参考资料,但那似乎过于复杂了,而且我还没有能够成功地检测到文件扩展名。根据我所能收集到的信息,当我的type变量为“image/jpeg”时,这段代码应该可以工作,但我只得到一个空字符串。
    MimeType mimeType = null;
    try {
        mimeType = new MimeTypes().forName(type);
    } catch (MimeTypeException e) {
        Logger.error("Couldn't Detect Mime Type for type: " + type, e);
    }

    if (mimeType != null) {
        String extension = mimeType.getExtension();
        //do something with the extension
    }

2
你确定需要设置文件扩展名吗?如果你知道MIME类型,你可以使用正确的“Content-Type”将其上传到S3,扩展名(通常)变得不相关。 - willglynn
2
你说得对,我刚刚检查了一下,在S3的ObjectMetadata中设置Content-Type就可以解决我的问题。但我仍然想知道这个问题的答案,因为在将来可能会用到。 - rphutchinson
1
好的。MIME类型到文件扩展名没有一个真正的映射 - 一些类型有多个扩展名,一些扩展名有多个类型 - 所以当我使用一个可以独立持久化两者的数据存储时,我尽量只存储我所知道的,并且避免猜测。 - willglynn
1个回答

77

正如一些评论者所指出的那样,mimetype和文件扩展名之间并不存在普遍的一对一映射关系。有些mimetype可能有多个可能的扩展名,许多扩展名被多个mimetype共享,而有些mimetype则没有扩展名。

在可能的情况下,最好将mimetype存储起来,并在以后使用它,忘记扩展名。

话虽如此,如果您确实想获取给定mimetype的最常见文件扩展名,那么Tika是一个不错的选择。 Apache Tika 知道非常多的mimetype,对于其中许多,它还知道mime magic用于检测、常见扩展名、描述等等。

如果你想要为JPEG文件获取最常见的扩展名,那么就像这个 Apache Tika 单元测试中所示,只需要执行类似以下内容的操作:

  MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
  MimeType jpeg = allTypes.forName("image/jpeg");
  String jpegExt = jpeg.getExtension(); // .jpg
  assertEquals(".jpg", jpeg.getExtension());

关键是需要加载Tika jar中捆绑的xml文件,以获取所有mimetype的定义。如果你可能也要处理自定义mimetype,那么Tika也支持这些,并将第一行更改为:

  TikaConfig config = TikaConfig.getDefaultConfig();
  MimeTypes allTypes = config.getMimeRepository();
通过使用TikaConfig方法获取MimeTypes,Tika还会检查您的类路径以获取自定义Mimetype定义,并将其包含在内。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接