使用Apache tika获取MimeType子类型

我需要获取iana.org MediaType,而不是应用程序/ zip或application / x-tika-msoffice用于像odt,ppt,pptx,xlsx等文档。

如果你看看mimetypes.xml,有mimeType元素由iana.org mime类型和“sub-class-of”

   <mime-type type="application/msword">
    <alias type="application/vnd.ms-word"/>
    ............................
    <glob pattern="*.doc"/>
    <glob pattern="*.dot"/>
    <sub-class-of type="application/x-tika-msoffice"/>
  </mime-type>

如何获得iana.org mime类型名称而不是父类型名称?

当测试MIME类型检测时,我这样做:

MediaType mediaType = MediaType.parse(tika.detect(inputStream));
String mimeType = mediaType.getSubtype();

检测结果 :

FAILED: getsCorrectContentType("application/vnd.ms-excel", docs/xls/en.xls)
java.lang.AssertionError: expected:<application/vnd.ms-excel> but was:<x-tika-msoffice>

FAILED: getsCorrectContentType("vnd.openxmlformats-officedocument.spreadsheetml.sheet", docs/xlsx/en.xlsx)
java.lang.AssertionError: expected:<vnd.openxmlformats-officedocument.spreadsheetml.sheet> but was:<zip>

FAILED: getsCorrectContentType("application/msword", doc/en.doc)
java.lang.AssertionError: expected:<application/msword> but was:<x-tika-msoffice>

FAILED: getsCorrectContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document", docs/docx/en.docx)
java.lang.AssertionError: expected:<application/vnd.openxmlformats-officedocument.wordprocessingml.document> but was:<zip>

FAILED: getsCorrectContentType("vnd.ms-powerpoint", docs/ppt/en.ppt)
java.lang.AssertionError: expected:<vnd.ms-powerpoint> but was:<x-tika-msoffice>

有没有什么办法从mimetypes.xml中获取实际的子类型? 而不是x-tika-msoffice或application / zip?

此外,我从来没有得到应用程序/ x-tika-ooxml,但应用程序/ zip为xlsx,docx,pptx文件。


最初,Tika只支持Mime Magic或文件扩展名(glob)的检测,因为这是Tika做过的所有大多数MIME检测。

由于Mime Magic和globs在检测容器格式方面存在问题,因此决定向Tika添加一些新的检测器来处理这些问题。 容器感知检测器获取整个文件,打开并处理容器,然后根据内容计算出确切的文件类型。 最初,您需要明确地调用它们,但随后它们被封装在ContainerAwareDetector ,您将在某些答案中看到它们。

从那以后,Tika增加了一个服务加载器模式,最初是为解析器。 这允许类在出现时自动加载,并且通过一般方法来识别哪些类是合适的并使用它们。 这个支持随后扩展到了探测器,在这一点上,旧的ContainerAwareDetector可以被删除,而转向更干净的东西。

如果您使用的是Tika 1.2或更高版本,并且想要准确检测所有格式(包括容器格式),则需要执行以下操作:

 TikaConfig config = TikaConfig.getDefaultConfig();
 Detector detector = config.getDetector();

 TikaInputStream stream = TikaInputStream.get(fileOrStream);

 Metadata metadata = new Metadata();
 metadata.add(Metadata.RESOURCE_NAME_KEY, filenameWithExtension);
 MediaType mediaType = detector.detect(stream, metadata);

如果你只用Core Tika jar(tika-core-1.2 -....)来运行它,那么唯一存在的探测器将会是mime magics one,并且你将得到基于magic + glob的旧式探测器。 然而,如果你使用Core和Parser Tika jars(以及它们的依赖项)或者Tika App(其中包括核心+解析器+依赖关系)自动运行它,那么DefaultDetector将使用所有不同的容器检测器来处理你的文件。 如果您的文件是基于zip的,那么检测将包括处理zip结构以基于其中的内容来识别文件类型。 这将为您提供高精度的检测,而无需依次调用大量不同的解析器。 DefaultDetector将使用所有可用的探测器。


对于任何其他有类似问题但使用新版Tika版本的人来说,这应该可以做到这一点:

  • 因为您可能没有任何ContainerAwareDetector所以使用ZipContainerDetector
  • TikaInputStream添加detect()器的detect()方法以确保tika可以分析正确的MIME类型。
  • 我的示例代码如下所示:

    public static String getMimeType(final Document p_document)
    {
        try
        {
            Metadata metadata = new Metadata();
            metadata.add(Metadata.RESOURCE_NAME_KEY, p_document.getDocName());
    
            Detector detector = getDefaultDectector();
    
            LogMF.debug(log, "Trying to detect mime type with detector {0}.", detector);
            TikaInputStream inputStream = TikaInputStream.get(p_document.getData(), metadata);
    
            return detector.detect(inputStream, metadata).toString();
        }
        catch (Throwable t)
        {
            log.error("Error while determining mime-type of " + p_document);
        }
    
        return null;
    }
    
    private static Detector getDefaultDectector()
    {
        if (detector == null)
        {
            List<Detector> detectors = new ArrayList<>();
    
            // zip compressed container types
            detectors.add(new ZipContainerDetector());
            // Microsoft stuff
            detectors.add(new POIFSContainerDetector());
            // mime magic detection as fallback
            detectors.add(MimeTypes.getDefaultMimeTypes());
    
            detector = new CompositeDetector(detectors);
        }
    
        return detector;
    }
    

    请注意, Document类是我的域模型的一部分。 所以你肯定会有类似的东西。

    我希望有人能使用它。


    tika-core中默认的字节模式检测规则只能检测所有MS Office文档类型使用的通用OLE2或ZIP格式。 您希望使用ContainerAwareDetector进行这种检测afaik。 并使用MimeTypes检测器作为其后备检测器。 尝试这个 :

    public MediaType getContentType(InputStream is, String fileName) {
        MediaType mediaType;
        Metadata md = new Metadata();
        md.set(Metadata.RESOURCE_NAME_KEY, fileName);
        Detector detector = new ContainerAwareDetector(tikaConfig.getMimeRepository());
    
        try {
            mediaType = detector.detect(is, md);
        } catch (IOException ioe) {
            whatever;
        }
        return mediaType;
    }
    

    这样你的测试应该通过

    链接地址: http://www.djcxy.com/p/7941.html

    上一篇: Getting MimeType subtype with Apache tika

    下一篇: What MIME type should I use for CSV?