首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用Apache获取MimeType子类型

使用Apache获取MimeType子类型
EN

Stack Overflow用户
提问于 2011-08-21 10:14:42
回答 4查看 30.9K关注 0票数 14

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

如果您查看mimetypes.xml,就会发现mimeType元素由iana.org mime类型和"sub-class- of“组成

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   <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类型检测时,我这样做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MediaType mediaType = MediaType.parse(tika.detect(inputStream));
String mimeType = mediaType.getSubtype();

测试结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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?

此外,我从未得到application/x-tika-ooxml,而是xlsx、docx、pptx文档的application/zip。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-22 09:19:33

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
}

这样你的测试就可以通过了

票数 2
EN

Stack Overflow用户

发布于 2012-07-01 15:04:10

最初,Tika只支持Mime Magic或文件扩展名(glob)的检测,因为这都是Tika之前的大多数mime检测。

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

从那时起,Tika添加了一个服务加载器模式,最初用于解析器。这允许类在存在时自动加载,并提供一种通用的方法来识别哪些类是合适的并使用它们。然后,这种支持也扩展到了检测器,在这一点上,旧的ContainerAwareDetector可以被移除,以支持更干净的东西。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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魔术检测器,并且您将获得仅基于魔术+ glob的旧式检测。但是,如果您同时使用核心和解析器Tika jar(加上它们的依赖项),或者从Tika App (自动包含核心+解析器+依赖项)运行,那么DefaultDetector将使用所有不同的容器检测器来处理您的文件。如果您的文件是基于zip的,那么检测将包括处理zip结构以根据其中的内容识别文件类型。这将为您提供您想要的高精度检测,而无需依次调用大量不同的解析器。DefaultDetector将使用所有可用的检测器。

票数 30
EN

Stack Overflow用户

发布于 2012-06-26 09:15:41

对于任何其他有类似问题但使用更新的Tika版本的人来说,这应该可以解决这个问题:

  1. 使用ZipContainerDetector,因为您可能不再有ContainerAwareDetector
  2. TikaInputStream赋予检测器的detect()方法,以确保tika可以分析正确的mime类型。

我的示例代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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类是我的域模型的一部分。所以你在这一行肯定会有类似的东西。

我希望有人能用上这个。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7137634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文