Java获取文件类型的5种方法

前言

工作中经常会用到,判断一个文件的文件类型,这里总结一把,一般判断文件类型的原理有2种方式:

  1. 根据文件扩展名判断

  • 优点:速度快,代码简单

  • 缺点:无法判断出真实的文件类型,例如一些伪造的文件或者没有后缀名称的文件

  • 根据文件流中前几个字符判断

    • 优点:可以判断出真实的文件类型

    • 缺点:速度慢,代码复杂

    下面我会针对每个方法,去测试验证,测试文件如下:

    1. test.png: 创建一个正常的png文件,其扩展名为test.png

    2. test.doc: 复制一份上面的test.png文件,修改其文件名称为test.doc

    1. 使用Files.probeContentType

    Java1.7开始,提供了用于解决MIME类型的方法 Files.probeContentType:

        public static void test() throws IOException {Path path = new File("d:/test.png").toPath();String mimeType = Files.probeContentType(path);System.out.println(mimeType);}
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docapplication/msword

    此方法利用已安装的FileTypeDetector实现来探查MIME类型。它调用每个实现的 probeContentType来解析类型。

    但是,其默认实现是特定于操作系统的,并且可能会失败,具体取决于我们使用的操作系统。

    结论:根据文件扩展名判断。

    2. 使用URLConnection

    URLConnection提供了几种用于检测文件的MIME类型的API。

    2.1 使用getContentType

    public void test(){File file = new File("d:/test.png");URLConnection connection = file.toURL().openConnection();String mimeType = connection.getContentType();
    }
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docimage/png✔️

    结论:根据文件流中前几个字符判断。能够判断真实的文件类型,但是,这种方法的主要缺点是速度非常慢

    2.2 使用guessContentTypeFromName

    public void test(){File file = new File("d:/test.png");String mimeType = URLConnection.guessContentTypeFromName(file.getName());
    }
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docnull❌ 具体参考下面的2.4

    该方法利用内部的FileNameMap来判断MIME类型。

    结论:根据文件扩展名判断。

    2.3 使用guessContentTypeFromStream

        public static void test() throws Exception {FileInputStream inputFile = new FileInputStream("d:/test.doc");String mimeType = URLConnection.guessContentTypeFromStream(new BufferedInputStream(inputFile));System.out.println(mimeType);}
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docimage/png✔️

    结论:根据文件流中前几个字符判断

    2.4 使用getFileNameMap

    使用URLConnection获得MIME类型的更快方法是使用getFileNameMap()方法:

    public void test(){File file = new File("d:/test.png");FileNameMap fileNameMap = URLConnection.getFileNameMap();String mimeType = fileNameMap.getContentTypeFor(file.getName());
    }
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docnull

    该方法返回URLConnection的所有实例使用的MIME类型表。然后,该表用于解析输入文件类型。

    当涉及URLConnection时,MIME类型的内置表非常有限。

    默认情况下,该类使用content-types.properties文件,其所在目录为JRE_HOME/lib。但是,我们可以通过使用content.types.user.table属性指定用户特定的表来扩展它 :

    System.setProperty("content.types.user.table","<path-to-file>");
    

    结论:根据文件扩展名判断。

    3. 使用MimeTypesFileTypeMap

    该类是Java 6附带的,因此在使用JDK 1.6时非常方便。

    public void test() {File file = new File("product.png");MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();String mimeType = fileTypeMap.getContentType(file.getName());
    }
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docapplication/octet-stream

    在这里,我们可以将文件名或File实例本身作为参数传递给函数。但是,以File实例为参数的函数在内部调用重载方法,该方法接受文件名作为参数。

    在内部,此方法查找名为mime.types的文件以进行类型解析。请务必注意,该方法以特定顺序搜索文件:

    1. 以编程方式将条目添加到MimetypesFileTypeMap实例

    2. 用户主目录中的mime.types

    3. <java.home> /lib/mime.types

    4. 名为META-INF / mime.types的资源

    5. 名为META-INF / mimetypes.default的资源(通常仅在activation.jar文件中找到)

    但是,如果找不到文件,它将返回application/octet-stream作为响应。

    结论:根据文件扩展名判断。

    4. 使用jmimemagic

    jMimeMagic是一个受限制许可的库,我们可以使用它来获取文件的MIME类型。

    配置Maven依赖:

    <dependency><groupId>net.sf.jmimemagic</groupId><artifactId>jmimemagic</artifactId><version>0.1.5</version>
    </dependency>
    

    接下来,我们将探讨如何使用该库:

    public void test() {File file = new File("d:/test.doc");MagicMatch match = Magic.getMagicMatch(file, false);System.out.println(match.getMimeType());
    }
    

    该库可以处理数据流,因此不需要文件存在于文件系统中。

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docimage/png✔️

    结论:根据文件流中前几个字符判断

    5. 使用Apache Tika

    Apache Tika是一个工具集,可检测并从各种文件中提取元数据和文本。它具有丰富而强大的API,并带有[tika-core],我们可以利用它来检测文件的MIME类型。

    配置Maven依赖:

    <dependency><groupId>org.apache.tika</groupId><artifactId>tika-core</artifactId><version>1.18</version>
    </dependency>
    

    接下来,我们将使用detect()方法来解析类型:

    public void whenUsingTika_thenSuccess() {File file = new File("d:/test.doc");Tika tika = new Tika();String mimeType = tika.detect(file);
    }
    

    结果

    文件结果结论
    test.pngimage/png✔️
    test.docimage/png✔️

    结论:根据文件流中前几个字符判断

    总结

    根据判断原理总结分类如下:

    判断原理方式
    根据文件扩展名1.Files.probeContentType
    2.URLConnection.guessContentTypeFromName
    3.URLConnection.getFileNameMap
    4.MimetypesFileTypeMap
    根据文件流中前几个字符1.URLConnection.getContentType
    2.URLConnection.guessContentTypeFromStream
    3.jmimemagic
    4.tika

    具体如何选择,依据需求而定

    参考:https://www.baeldung.com/java-file-mime-type

    
    往期推荐
    

    最常见的10种Java异常问题!


    SpringBoot接口幂等性实现的4种方案!


    对象复制的7种方法,还是Spring的最好用!


    关注我,每天陪你进步一点点!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你以为用了BigDecimal后,计算结果就一定精确了?

BigDecimal&#xff0c;相信对于很多人来说都不陌生&#xff0c;很多人都知道他的用法&#xff0c;这是一种java.math包中提供的一种可以用来进行精确运算的类型。很多人都知道&#xff0c;在进行金额表示、金额计算等场景&#xff0c;不能使用double、float等类型&#xff0c;…

Google 开源的依赖注入库,比 Spring 更小更快!

来源 | zhuanlan.zhihu.com/p/24924391Guice是Google开源的一个依赖注入类库&#xff0c;相比于Spring IoC来说更小更快。Elasticsearch大量使用了Guice&#xff0c;本文简单的介绍下Guice的基本概念和使用方式。学习目标概述&#xff1a;了解Guice是什么&#xff0c;有什么特点…

这个 bug 让我更加理解 Spring 单例了

谁还没在 Spring 里栽过跟头呢&#xff0c;从哪儿跌倒&#xff0c;就从哪儿睡一会儿&#xff0c;然后再爬起来。讲点儿武德 这是由一个真实的 bug 引起的&#xff0c;bug 产生的原因就是忽略了 Spring Bean 的单例模式。来&#xff0c;先看一段简单的代码。public class TestS…

mysql优化--叶金荣老师讲座笔记

copy to tmp table执行ALTER TABLE修改表结构时建议&#xff1a;凌晨执行Copying to tmp table拷贝数据到内存中的临时表&#xff0c;常见于GROUP BY操作时建议&#xff1a;创建索引Copying to tmp table on disk临时结果集太大&#xff0c;内存中放不下&#xff0c;需要将内存…

废弃fastjson!大型项目迁移Gson保姆级实战

前言本篇文章是我这一个多月来帮助组内废弃fastjson框架的总结&#xff0c;我们将大部分Java仓库从fastjson迁移至了Gson。这么做的主要的原因是公司受够了fastjson频繁的安全漏洞问题&#xff0c;每一次出现漏洞都要推一次全公司的fastjson强制版本升级&#xff0c;很令公司头…

学到了!MySQL 8 新增的「隐藏索引」真不错

MySQL 8.0 虽然发布很久了&#xff0c;但可能大家都停留在 5.7.x&#xff0c;甚至更老&#xff0c;其实 MySQL 8.0 新增了许多重磅新特性&#xff0c;比如栈长今天要介绍的 "隐藏索引" 或者 "不可见索引"。隐藏索引是什么鬼&#xff1f; 隐藏索引 字面意思…

iOS开发-自定义UIAlterView(iOS 7)

App中不可能少了弹框&#xff0c;弹框是交互的必要形式&#xff0c;使用起来也非常简单&#xff0c;不过最近需要自定义一个弹框&#xff0c;虽然iOS本身的弹框已经能满足大部分的需求&#xff0c;但是不可避免还是需要做一些自定义的工作。iOS7之前是可以自定义AlterView的&am…

Spring 事务失效的 8 大场景,面试官直呼666...

前几天发了一篇文章里面有一个关于事务失效的问题&#xff1a;用 Spring 的 Transactional 注解控制事务有哪些不生效的场景&#xff1f;其中有个热心粉丝留言分享了下&#xff0c;我觉得总结得有点经验&#xff0c;给置顶了&#xff1a;但是我觉得还是总结得不够全&#xff0c…

认真聊一下MySQL索引的底层实现!

前言当我们发现SQL执行很慢的时候&#xff0c;自然而然想到的就是加索引&#xff0c;当然他也是高频的面试问题&#xff0c;所以今天我们一起来学习一下MySQL索引的底层实现&#xff1a;B树。树简介、树种类B-树、B树简介B树插入B树查找B树删除B树经典面试题树的简介树的简介树…

最新大厂面试真题集锦

年后又是一波求职季&#xff0c;正是“金三银四”这个求职黄金期&#xff0c;很多人扎堆在这个时间段跳槽&#xff0c;找工作&#xff0c;程序员也不例外。春节刚过&#xff0c;各公司企业都开始启动了新一年的招聘计划&#xff0c;招聘岗位倍增&#xff0c;求职人数远超于岗位…

使用OpenCV在Python中进行人脸和眼睛检测

Modules Used: 使用的模块&#xff1a; python-opencv(cv2)python-opencv(cv2) python-opencv(cv2) Opencv(Open source computer vision) is a python library that will help us to solve computer vision problems. Opencv(开源计算机视觉)是一个Python库&#xff0c;可帮…

Java打造一款SSH客户端,已开源!

最近由于项目需求&#xff0c;项目中需要实现一个WebSSH连接终端的功能&#xff0c;由于自己第一次做这类型功能&#xff0c;所以首先上了GitHub找了找有没有现成的轮子可以拿来直接用&#xff0c;当时看到了很多这方面的项目&#xff0c;例如&#xff1a;GateOne、webssh、she…

我去,这几个Linux指令太装B了|动图展示

1. sl先看一下呼啸而过的火车&#xff1b;安装指令如下&#xff1b;sduo apt-get install sl执行结果如下&#xff1a;2. htop图形化Linux系统性能监测工具&#xff0c;屌不屌:安装指令如下:sduo apt-get install htop执行结果如下&#xff1b;3. gcp以前用cp复制文件总是看不懂…

书店POS机--细化迭代2--测试

2019独角兽企业重金招聘Python工程师标准>>> (1) 开始一次新的销售&#xff0c;点击书店POS系统的销售&#xff1a; (2) 进入销售模块之后的界面如下&#xff1a; (3)逐条录入商品条目(根据商品编号)&#xff0c;并修改数量。确认无误之后点击“确认”按钮&#x…

Google Guava,牛逼的脚手架

01、前世今生你好呀&#xff0c;我是 Guava。1995 年的时候&#xff0c;我的“公明”哥哥——Java 出生了。经过 20 年的发展&#xff0c;他已经成为世界上最流行的编程语言了&#xff0c;请允许我有失公允的把“之一”给去了。虽然他时常遭受着各种各样的吐槽&#xff0c;但他…

阿里巴巴Druid,轻松实现MySQL数据库加密!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;为什么要加密&#xff1f;现在的开发习惯&#xff0c;无论是公司的项目还是个人的项目&#xff0c;都会选择将源码上传到 Gi…

计算机图形学图形旋转_计算机图形学中的平板显示

计算机图形学图形旋转平板显示器 (Flat Panel Display) It is generally known as FPD, the flat-panel display is such a display technology which overtakes Cathode Ray Tube as a new standard of computer desktop displays. Unlike monitors through CRT, flat-panel d…

一文掌握Redisson分布式锁原理|干货推荐

ReentrantLock 重入锁在说 Redisson 之前我们先来说一下 JDK 可重入锁: ReentrantLockReentrantLock 保证了 JVM 共享资源同一时刻只允许单个线程进行操作实现思路ReentrantLock 内部公平锁与非公平锁继承了 AQS[AbstractQueuedSynchronizer]1、AQS 内部通过 volatil 修饰的 in…

7种分布式事务的解决方案,一次讲给你听

本文约5300字&#xff0c;阅读时长「5分钟」什么是分布式事务分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器「分别位于不同的分布式系统的不同节点之上」。一个大的操作由N多的小的操作共同完成。而这些小的操作又分布在不同的服务上。针对于这些操…

css @media 响应式布局

2019独角兽企业重金招聘Python工程师标准>>> &#xfeff;1、在 html 标签中 <link rel"stylesheet" type"text/css" href"style1.css" media"screen and (min-width: 600px) and (max-width: 800px)"> 2、在样式表中…