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,一经查实,立即删除!

相关文章

OpenCart 之 CSV 格式商品导入 – 如何导入商品主图片和附加图片?

1. 在文件中定义多个附加图片可以为一个商品导入多个图片。这些图片需要以“附加图片分隔符”来分割&#xff0c;而附加图片分隔符的定义在扩充功能配置页面。下面是一个带有URL链接的多个图片的填写格式&#xff1a;…,”http://www.example.com/p_w_picpath1.png:::http://ww…

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

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

tohexstring方法_Java Float类toHexString()方法的示例

tohexstring方法浮动类toHexString()方法 (Float class toHexString() method) toHexString() method is available in java.lang package. toHexString()方法在java.lang包中可用。 toHexString() method is used to represent a hexadecimal string of the given parameter […

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

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

Servlet页面跳转实现方法的区别

Servlet页面跳转实现方法的区别 http://developer.51cto.com/art/200907/133803.htm本文向您介绍Servlet页面跳转实现方法的几种区别&#xff0c;包括Servlet和JSP中的不同实现&#xff0c;比如Servlet中的redirect方式和forward方式得区别等。一直对Servlet页面跳转的几种方式…

Java Double类shortValue()方法与示例

双类shortValue()方法 (Double class shortValue() method) shortValue() method is available in java.lang package. shortValue()方法在java.lang包中可用。 shortValue() method is used to return the value denoted by this Double object converted to type short (by c…

这个 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;需要将内存…

JS判断文本框中只能输入数字和小数点

http://liva-zheng.iteye.com/blog/1733827 1.文本框只能输入数字(不包括小数点) <input οnkeyup"this.valuethis.value.replace(/\D/g,)" onafterpaste"this.valuethis.value.replace(/\D/g,)"> 2.只能输入数字和小数点. <input οn…

java 方法 示例_Java集合asLifoQueue()方法和示例

java 方法 示例集合类asLifoQueue()方法 (Collections Class asLifoQueue() method) asLifoQueue() Method is available in java.lang package. asLifoQueue()方法在java.lang包中可用。 asLifoQueue() Method is used to represent the given deque as a Lifo queue (LIFO me…

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

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

网页如何做到适应在手机上浏览

http://bbs.php100.com/read-htm-tid-482066.html 目前有很多不错的mobile开发框架可以使用&#xff0c;这些框架已经为手机端的特殊性提供了很好的支持和效果插件&#xff0c;比如&#xff1a;jquery mobile、kendoui等~~ 不过&#xff0c;谢谢框架因为其开源性或商业化&…

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

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

Java ClassLoader findLibrary()方法与示例

ClassLoader类findLibrary()方法 (ClassLoader Class findLibrary() method) findLibrary() method is available in java.lang package. findLibrary()方法在java.lang包中可用。 findLibrary() method is used to find the absolute pathname of the given native library. f…

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

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

jsp中redirect和forward的区别

在网上看到一些帖子&#xff0c;总结了一些区别&#xff0c;可以从以下几个方面来看&#xff1a;1.从地址栏显示来说 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来…

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

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

python 示例_Python条件类| release()方法与示例

python 示例Python Condition.release()方法 (Python Condition.release() Method) release() is an inbuilt method of the Condition class of the threading module in Python. release()是Python中线程模块的Condition类的内置方法。 Condition class implements conditio…

Java BigInteger类| hashCode()方法与示例

BigInteger类hashCode()方法 (BigInteger Class hashCode() method) hashCode() method is available in java.math package. hashCode()方法在java.math包中可用。 hashCode() method is used to return the hash code value of this BigInteger. hashCode()方法用于返回此Big…

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

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