使用tika 判断文件类型

判断文件类型一般可采用两种方式

后缀名判断

简单易操作,但无法准确判断类型

文件头信息判断

通常可以判断文件类型,但有些文件类型无法判断(如word和excel头信息的前几个字节是一样的,无法判断)

Apache Tika 是什么?

  • Apache Tika用于文件类型检测和从各种格式的文件内容提取的库。
    在内部,Tika使用现有的各种文件解析器和文档类型的检测技术来检测和提取数据。
  • 使用Tika,人们可以开发出通用型检测器和内容提取到的不同类型的文件,如电子表格,文本文件,图像,PDF文件甚至多媒体输入格式,在一定程度上提取结构化文本以及元数据。
  • Tika提供用于解析不同文件格式的一个通用API。它采用83个现有的专业解析器库,为每个文档类型。
  • 所有这些解析器库是根据一个叫做Parser接口单一接口封装。

Tika类型检测

Tika支持MIME所提供的所有互联网媒体文件类型。每当一个文件通过Tika检测到该文件,其文件类型。检测的介质类型,Tika内部通过以下机制。

MIME标准

多用途Internet邮件扩展(MIME)标准,用于识别文件类型的最佳标准。这些标准的知识有助于在内部相互作用的浏览器。

当浏览器遇到一个媒体文件,它选择可用它来显示其内容的兼容软件。在情况下,它不具有任何合适的应用程序,以运行一个特定媒体文件,它建议用户获得合适的插件软件。

springboot 中使用

引入依赖

        <!-- 上传文件验证 -->
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>1.9</version>
        </dependency>

文件类型判断工具类

package com.cloudDisk.utils.file;

import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.HttpHeaders;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaMetadataKeys;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 成大事
 * @date 2021-12-20
 */
public class FileTypeJudge {
 /**
     * 获取类型
     * @param multipartFile  文件
     * @return mineType
     */
    public static String getMimeTypeFile(MultipartFile multipartFile) throws Exception {
        File file = MultipartFileToFile.multipartFileToFile(multipartFile);
        if (file.isDirectory()) {
            return "the target is a directory";
        }

		 //创建自动检测解析器
        AutoDetectParser parser = new AutoDetectParser();
        parser.setParsers(new HashMap<MediaType, Parser>());

        Metadata metadata = new Metadata();
        metadata.add(TikaMetadataKeys.RESOURCE_NAME_KEY, file.getName());

        InputStream stream;
        try {
            stream = new FileInputStream(file);
            parser.parse(stream, new DefaultHandler(), metadata, new ParseContext());
            stream.close();
        } catch (TikaException | SAXException | IOException e) {
            e.printStackTrace();
        }
        //将产生的临时文件删除
        MultipartFileToFile.deleteTempFile(file);
        return metadata.get(HttpHeaders.CONTENT_TYPE);
    }
}

类型转换工具类

一般情况下,都是通过multipleFile来接收文件。但是tika是判断file 的。所以需要一个工具类将multiplefile转成file

package com.cloudDisk.utils.file;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author 成大事
 * @since 2022/5/11 10:20
 */
public class MultipartFileToFile {

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     * @param file
     */
    public static void deleteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }
}

测试

 @GetMapping("/testUpload")
    public R testUpload(
            @RequestParam("file") MultipartFile file
    ) throws Exception {
        String mimeType = FileTypeJudge.getMimeTypeFile(file);
        log.info("tika 的格式{}",mimeType);
        return R.ok(mimeType);
    }

使用apiPost 测试发送文件
在这里插入图片描述
查看:
在这里插入图片描述

残留问题

就是不能直接对multiplefile的类型进行判断,得先转换成file的类型。之前参考的一篇博客

https://blog.csdn.net/weixin_43194885/article/details/109747552

可以实现简单的一些文件的判断。但是比如pptx,word还有xlsx都识别成application/zip。所以还是有问题。希望能解决的大佬可以帮忙指正修改一下。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值