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

问题描述 投票:0回答:2

我正在将文件上传到 Amazon s3 存储桶,并有权访问 InputStream 和包含文件 MIME 类型但不包含原始文件名的字符串。在将文件推送到 S3 之前,由我实际创建文件名和扩展名。是否有库或方便的方法来确定要从 MIME 类型使用的适当扩展名?

我已经看到了一些对 Apache Tika 库的引用,但这似乎有点矫枉过正,而且我还无法让它成功检测文件扩展名。从我收集到的信息看来,这段代码应该可以工作,但是当我的类型变量是“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
    }
java amazon-s3 apache-tika
2个回答
78
投票

正如一些评论者所指出的,mimetypes 和文件扩展名之间不存在通用的 1:1 映射...某些 mimetypes 具有多个可能的扩展名,许多扩展名由多个 mimetypes 共享,而某些 mimetypes 没有扩展名。

只要有可能,最好存储 mimetype 并继续使用它,而忘记扩展名。

也就是说,如果您确实想获得给定 mimetype 最常见的文件扩展名,那么 Tika 是一个不错的选择。 Apache Tika 拥有大量它所了解的 mimetypes,并且对于其中许多类型,它还了解用于检测、常见扩展、描述等的 mime 魔法。

如果您想获得 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 的定义。如果您也可能正在处理自定义 mimetypes,那么 Tika 支持这些,并将第一行更改为:

  TikaConfig config = TikaConfig.getDefaultConfig();
  MimeTypes allTypes = config.getMimeRepository();

通过使用 TikaConfig 方法获取 MimeTypes,Tika 还将检查您的类路径中是否有自定义 mimetype 定义,并包含这些定义。


0
投票

我的解决方案:

创建一个MimeService接口,一个MimeServiceImpl实现。然后在类路径中创建一个mime.properties。 StreamUtils.toProperties(fileName) 是一个自制的 util 类,它从类路径加载属性文件。

public class MimeServiceImpl implements MimeService
{
    private static final Logger LOG = 
       LoggerFactory.getLogger(MimeServiceImpl.class);

    protected Properties mapping;

    public MimeServiceImpl()
    {
        this.mapping = StreamUtils.toProperties("mime.properties");
        for(String key : this.mapping.stringPropertyNames())
        {
            String value = this.mapping.getProperty(key);
            LOG.info("{}={}", key, value);
        }
    }

    @Override
    public String getMime(String ext) {
        return StringUtils.isNotBlank(ext) ? 
            this.mapping.getProperty(ext.trim().toLowerCase()) : null;
    }
}

mime.properties(键=扩展文件,值=mime)

json=application/json
zip=application/octet-stream
pdf=application/pdf 
xls=application/vnd.ms-excel 
xlsx=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
htm=text/html 
html=text/html 
xml=text/xml
txt=text/plain  
js=application/javascript
jpeg=image/jpeg
jpg=image/jpeg
png=image/png
gif=image/gif
tiff=image/tiff
doc=application/msword
rtf=application/msword

如果您需要更多映射,只需在属性文件中添加另一个条目即可。

如果您像库一样使用此代码,并且需要扩展映射,请在类路径项目中创建一个新的 mime.properties 并添加所需的所有新条目。

© www.soinside.com 2019 - 2024. All rights reserved.