Apache Tika - 检测 JSON / PDF 特定的 MIME 类型

4

我正在使用Apache Tika来检测一个文件的Mime类型,这个文件是用base64表示的。不幸的是,我没有其他关于文件的信息(例如扩展名)。

有什么方法可以让Tika更加具体吗?

我目前正在使用以下代码:

Tika tika = new Tika();
tika.setMaxStringLength(-1);
String mimetype = tika.detect(Base64.decode(fileString));

它给我返回了text/plain格式的JSON和PDF文件,但是我想要更具体的信息:application/jsonapplication/pdf等...

希望有人能够帮助我!

谢谢。


2
Base64.decode(fileString).getBytes() 就足以正确检测 PDF 文件。有关 JSON 部分,请参见我的下面的答案 - DJDaveMark
2个回答

5

Tika#detect(String)

该方法用于检测给定文件名的文档媒体类型。

如果您传递PDF或JSON文件的内容,则不会起作用,因为该方法需要文件名。Tika会回退到text/plain,因为它找不到匹配的文件名。

PDF

对于PDF文件,您只需将一些数据写入流或者传递一些字节并让Tika通过查找文件开头附近的特殊(“Magic”)字节模式(在纯文本中是%PDF)来读取这些数据,使用Mime Magic Detection即可。

String pdfContent = "%PDF-1.4\n%\\E2\\E3\\CF\\D3"; // i.e. base64 decoded
Tika tika = new Tika();
System.out.println(tika.detect(pdfContent.getBytes())); // "application/pdf"

JSON

对于JSON数据,即使使用上述方法,返回的仍然是text/plain,Tika的判断是正确的。 application/json实际上是纯文本的一种子类型,旨在指示该文本应以不同的方式进行解释。因此,如果您获得了text/plain数据,则需要使用JSON库(例如Jackson)来解析内容并查看其是否为有效的JSON数据:

Sring json = "[1, 2, 3]"; // an array in JSON
try {
    final JsonParser parser = new ObjectMapper().getFactory().createParser(json);
    while (parser.nextToken() != null) {
    }
    System.out.println("Probably JSON!");
} catch (Exception e) {
    System.out.println("Definitely not JSON!");
}

当心你希望严格的程度,因为Jackson把单个数字1视为有效的JSON,但实际上不是。为了解决这个问题,你可以首先测试字符串是否以{[(可能在空格之前)开头,例如使用json.matches("^\\s*[{\\[].*"),然后再试图将其解析为JSON。

这是一个关于Jackson的DZone教程


4

在我的过去项目中,我使用了 TikaConfig

我的做法是:

//Note you can use alse byte[] instead of InputStream
InputStream is = new FileInputStream(new File(YOUR_FILE));
TikaConfig tc = new TikaConfig();
Metadata md = new Metadata();
md.set(Metadata.RESOURCE_NAME_KEY, fileName);
String mimeType = tc.getDetector().detect(TikaInputStream.get(is), md).toString();

通过使用 byte[] :
byte[] fileBytes = GET_BYTE_ARRAY_FROM_YOUR_FILE;
TikaConfig tc = new TikaConfig();
Metadata md = new Metadata();
md.set(Metadata.RESOURCE_NAME_KEY, fileName);
String mimeType = tc.getDetector().detect(TikaInputStream.get(fileBytes), md).toString();

我没有遇到任何问题就获取了正确的mimeType...

希望这对你有用

Angelo


1
谢谢您的回答,问题是我没有文件名,只有文件的base64字符串表示。 - Briston12
您可以使用一个虚假的文件名。 - Angelo Immediata
1
但他在Tika中遇到的问题是无法给出确切的mimeType - 而是应该是application/json而不是text/plain。 - acthota
如果你检查流的话,它将是application/json。你应该做的是编写一个临时文件,然后让Tika来检查这个临时文件。 - Angelo Immediata
同意Tika对JSON文件的处理有些"懒散"。同样的情况也出现在CSV文件上,导致的结果是text/plain而不是text/csv - undefined

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